반응형

1. 자바란 무엇인가?


Java는 범용 프로그래밍 언어로 썬 마이크로 시스템즈(Sun Microsystems)에서 개발한 언어이다. 현재는 오라클(Oracle)에서 소유권을 가지고 있으며 유료화가 진행된 상태이다. 자바의 가장 큰 특징 중 하나는 플랫폼에 귀속되지 않는 다는 점이다. 코딩을 한번 하고 어떤 플랫폼이던지 간에 사용할 수 있게 만들어졌다. 이는 JVM이라 하는 자바가상머신을 이용해서 플랫폼에 관계 없이 사용할 수 있다. 이러한 특징으로 인해 자바는 많은 인기를 얻게 되었는데, 이는 프로그래밍 언어 순위 차트를 다루는 TIOBE에 가서 확인해도 높은 순위에 있는 것을 확인할 수 있다. 

 

1순위는 C언어, 2순위는 Java, 3순위는 Python이다. 만약에 프로그래밍이 처음이라면 개인적으로 Python을 추천한다. (아니 왜 방금 전까지 Java짱짱맨 해놓고선 Python이라뇨? 정말로 프로그래밍 자체가 처음이라면 순위보다는 일단 입문을 python으로 시작하라는 것이다. 비교적 쉬운 python을 통해 접근해보고 난이도를 낮춘 뒤에 다시 Java를 접근하는 것을 추천한다. 내가 필요한 건 모래성 쌓기인데, 갑자기 중장비 끌고 와서 고층 빌딩을 지을 순 없지 않겠는가? 그렇기에 프로그래밍 경험이 전무하다면 차라리 Python이 낫다는 것이다. 물론 읽는 것을 좋아하며, 수학을 좋아하고 딱딱한 이과감성을 사랑하는 사람이라면 Java, C, C++을 추천한다. 그렇지 않다면 일단은 Python을 통해 경험한 뒤에 들어와도 늦지 않다. 어차피 프로그래밍으로 입문해서 전문가까지 가려는 사람이라면 모든 언어는 다 써봐야 한다. 직업으로 일하려면 상황에 맞는 언어를 사용해야 하므로 언제나 다양한 언어가 필요한 것이다. 고로 결론. 시작은 Python을 추천한다.)

 

C/C++에서 Java로 넘어오면서 아주아주아주 편해진 점 중 하나는 메모리 관리의 자유로움이었다. C/C++가 개발자에게 많은 자유를 주는 만큼 주의해야 할 점이 많았는데, 대표적으로 메모리 관리이다. 그래서 C/C++는 초보자가 진입하기 어려운 장벽이 생겨버렸지만, 그만큼 성능 좋은 코드를 짤 수 있게 되었다. 하지만 현대의 하드웨는 이미 끝을 달리고 있다. 그러므로 우리는 하드웨어를 신경쓸 것이 아니라 내 생각을 구현하는게 더 중요해졌다. 그래서 자동으로 메모리 관리를 해주는 프로그래밍 언어를 쓸 필요성이 있는 것이다. Java와 파이썬은 그러하다.

 

2. 자바의 기본 로고


자바의 기본 로고는 이렇게 생겼다. 커피에 있는 자바인가? 그렇다. 필자도 대학교에서 C/C++를 하고 Java를 처음으로 선택했다. 이유는 로고가 그럴싸해서이다. 현재 자바는 오라클이 소유하고 있으며 유료화가 진행됬다. 그렇다고 무조건 유료는 아니다. 오픈소스가 존재한다. 우리는 오픈소스를 활용해서 진행하려고 한다. 

 

 

3. 설치 및 실행


jdk.java.net/15/

 

JDK 15.0.2 GA Release

JDK 15.0.2 General-Availability Release This page provides production-ready open-source builds of the Java Development Kit, version 15, an implementation of the Java SE 15 Platform under the GNU General Public License, version 2, with the Classpath Exce

jdk.java.net

이곳을 통해서 Java를 받으면 된다. JDK15를 기준으로 진행할 예정이므로 우리도 JDK 15를 받아주면 된다. 

대부분은 윈도우를 사용하고 있으므로 윈도우로 다운로드 받으면 된다. (참고로 여기는 Zip파일이다. 우리가 평소에 받던 exe파일이 아니라 자동 설치따윈 없다. ) 다운로드 받은 뒤에 원하는 장소에 압축을 풀어준다.

필자는 C를 사랑하는 사람이므로 C에다가 Java폴더를 만들어준 뒤에 압축을 풀어주었다. (정확한 이유는 D는 하드드라이브이기 때문에 SSD인 C에다가 풀어주었다.)

 

다 풀고 나면 C:\java\jdk-15.0.2 이러한 형태로 나오게 된다. 

자 이제 안타깝게도 자바를 사용하려면 바로 쓸 수 없다. 물론 바로 사용은 가능하다. 하지만 명령프롬프트를 사용해서 직접 실행파일이 있는 곳으로 끌고 가야 한다. 그래도 한번 해보자.

 

명령프롬프트를 사용하려면 

 

시작버튼 옆에 검색라인에 cmd라 타이핑하자. 그러면 명령프롬프트가 나온다. 명령프롬프트에다가 다음을 입력해보자.

 

cd.. 은 폴더의 하위 폴더로 가게 해준다. 그리고 아까 압축해제한 폴더에서 C:\java\jdk-15.0.2\bin를 찾아둔다. 그리고 cd C:\java\jdk-15.0.2\bin을입력하면 위에 상황과 같이 된다. 

 

여기에 두 가지 명령어를 입력해볼 수 있는데, java -version과 javac이다.

javac는 java의 컴파일러로 우리가 코딩을 해놓은 소스코드를 실행가능한 파일로 바꿔주는 역할을 한다. java 명령어는 바꿔놓은 파일을 java를 통해 실행할 수 있게끔 한다. (일반적으로 윈도우 환경에서 IDE를 사용하게 되면 이러한 내용은 몰라도 상관없다. 하지만 서버환경에서나 IDE가 없는 경우는 이렇게 컴파일하고 실행해야 한다. 그래서 한번은 이렇게라도 진행해보는 것이 중요하다. ) 

* IDE는 통합개발툴인데, 비주얼 스튜디오, 비주얼 스튜디오 코드, 인텔리제이와 같은 것을 의미한다.

 

자 그렇다면 매번 이렇게 귀찮게 실행해야 하는가 싶지만 그렇지 않다. 우리는 환경변수를 활용해서 자바가 설치된 폴더까지 안 가더라도 언제 어디서든 사용할 수 있도록 만들어 줄 것이다. 일반적으로 환경변수는 PATH를 설정해준다고 하는데, 컴퓨터한테 자바가 어디에 설치되어 있는지 알려주는 이정표 역할을 해주는 것이다. 

 

4. 자바 환경변수 설정하기


자바 환경변수 설정에는 명령프롬프트를 활용하는 방법과 시스템 환경설정을 통해서 하는 방법이 있는데, 명령프롬프트를 이용한 방법은 명령프롬프트가 꺼지면 초기화된, 시스템 환경설정을 이용해서 진행하도록 한다.

 

제어판 -> 시스템 정보 -> 고급 시스템 설정을 클릭한다.  [혹은 내 컴퓨터(내 PC) -> 오른쪽 클릭 -> 속성]

 

고급 시스템 설정을 클릭한 뒤에 -> 환경변수를 눌러준다. 

그 뒤에 새로 만들기를 눌러준다.

 

 

시스템 변수 편집에서 변수 이름에는 JAVA_HOME을 적어주고 변수 값에는 Java가 설치된 공간을 넣어주면 된다. 컴퓨터에게 자바가 여기에 설치되어 있다고 알려주는 것이다. 경로에 대한 변수를 할당하며, 그 변수는 JAVA_HOME이다. 대부분의 Java IDE 가 JAVA_HOME을 쓰고 있으므로 우리도 그에 따라 맞춰서 저장한다.

 

그 다음으로 Path를 입력할 것이다. 

Path를 눌러주고 편집을 누르자.

 

그러면 이렇게 나오게되는데, 

여기서 %JAVA_HOME%bin 을 입력해주자. 이것은 아까 저장한 JAVA_HOME이라는 변수에는 자바가 어디에 설치되어 있는지 알려주는 경로가 들어있다. 그곳에서 bin폴더가 있는 곳을 알려주는 것이다. (여기서 bin의 의미는 binary의 bin이다. 일반적으로 실행파일의 의미를 가지고 있다. 그래서 실행파일의 위치는 여기에 있다. 라고 알려준 것이다.)

 

여기까지만 해도 충분히1. 자바란 무엇인가?

Java는 범용 프로그래밍 언어로 썬 마이크로 시스템즈(Sun Microsystems)에서 개발한 언어이다. 현재는 오라클(Oracle)에서 소유권을 가지고 있으며 유료화가 진행된 상태이다. 자바의 가장 큰 특징 중 하나는 플랫폼에 귀속되지 않는 다는 점이다. 코딩을 한번 하고 어떤 플랫폼이던지 간에 사용할 수 있게 만들어졌다. 이는 JVM이라 하는 자바가상머신을 이용해서 플랫폼에 관계 없이 사용할 수 있다. 이러한 특징으로 인해 자바는 많은 인기를 얻게 되었는데, 이는 프로그래밍 언어 순위 차트를 다루는 TIOBE에 가서 확인해도 높은 순위에 있는 것을 확인할 수 있다. 

 

 

 

1순위는 C언어, 2순위는 Java, 3순위는 Python이다. 만약에 프로그래밍이 처음이라면 개인적으로 Python을 추천한다. (아니 왜 방금 전까지 Java짱짱맨 해놓고선 Python이라뇨? 정말로 프로그래밍 자체가 처음이라면 순위보다는 일단 입문을 python으로 시작하라는 것이다. 비교적 쉬운 python을 통해 접근해보고 난이도를 낮춘 뒤에 다시 Java를 접근하는 것을 추천한다. 내가 필요한 건 모래성 쌓기인데, 갑자기 중장비 끌고 와서 고층 빌딩을 지을 순 없지 않겠는가? 그렇기에 프로그래밍 경험이 전무하다면 차라리 Python이 낫다는 것이다. 물론 읽는 것을 좋아하며, 수학을 좋아하고 딱딱한 이과감성을 사랑하는 사람이라면 Java, C, C++을 추천한다. 그렇지 않다면 일단은 Python을 통해 경험한 뒤에 들어와도 늦지 않다. 어차피 프로그래밍으로 입문해서 전문가까지 가려는 사람이라면 모든 언어는 다 써봐야 한다. 직업으로 일하려면 상황에 맞는 언어를 사용해야 하므로 언제나 다양한 언어가 필요한 것이다. 고로 결론. 시작은 Python을 추천한다.)

 

 

 

2. 자바의 기본 로고

 

자바의 기본 로고는 이렇게 생겼다. 커피에 있는 자바인가? 그렇다. 필자도 대학교에서 C/C++를 하고 Java를 처음으로 선택했다. 이유는 로고가 그럴싸해서이다. 현재 자바는 오라클이 소유하고 있으며 유료화가 진행됬다. 그렇다고 무조건 유료는 아니다. 오픈소스가 존재한다. 우리는 오픈소스를 활용해서 진행하려고 한다. 

 

 

 

 

 

3. 설치 및 실행

jdk.java.net/15/

 

JDK 15.0.2 GA Release

 

JDK 15.0.2 General-Availability Release This page provides production-ready open-source builds of the Java Development Kit, version 15, an implementation of the Java SE 15 Platform under the GNU General Public License, version 2, with the Classpath Exce

 

jdk.java.net

이곳을 통해서 Java를 받으면 된다. JDK15를 기준으로 진행할 예정이므로 우리도 JDK 15를 받아주면 된다. 

 

 

대부분은 윈도우를 사용하고 있으므로 윈도우로 다운로드 받으면 된다. (참고로 여기는 Zip파일이다. 우리가 평소에 받던 exe파일이 아니라 자동 설치따윈 없다. ) 다운로드 받은 뒤에 원하는 장소에 압축을 풀어준다.

 

필자는 C를 사랑하는 사람이므로 C에다가 Java폴더를 만들어준 뒤에 압축을 풀어주었다. (정확한 이유는 D는 하드드라이브이기 때문에 SSD인 C에다가 풀어주었다.)

 

 

 

다 풀고 나면 C:\java\jdk-15.0.2 이러한 형태로 나오게 된다. 

 

자 이제 안타깝게도 자바를 사용하려면 바로 쓸 수 없다. 물론 바로 사용은 가능하다. 하지만 명령프롬프트를 사용해서 직접 실행파일이 있는 곳으로 끌고 가야 한다. 그래도 한번 해보자.

 

 

 

명령프롬프트를 사용하려면 

 

시작버튼 옆에 검색라인에 cmd라 타이핑하자. 그러면 명령프롬프트가 나온다. 명령프롬프트에다가 다음을 입력해보자.

 

 

cd.. 은 폴더의 하위 폴더로 가게 해준다. 그리고 아까 압축해제한 폴더에서 C:\java\jdk-15.0.2\bin를 찾아둔다. 그리고 cd C:\java\jdk-15.0.2\bin을입력하면 위에 상황과 같이 된다. 

여기에 두 가지 명령어를 입력해볼 수 있는데, java -version과 javac이다.

 

javac는 java의 컴파일러로 우리가 코딩을 해놓은 소스코드를 실행가능한 파일로 바꿔주는 역할을 한다. java 명령어는 바꿔놓은 파일을 java를 통해 실행할 수 있게끔 한다. (일반적으로 윈도우 환경에서 IDE를 사용하게 되면 이러한 내용은 몰라도 상관없다. 하지만 서버환경에서나 IDE가 없는 경우는 이렇게 컴파일하고 실행해야 한다. 그래서 한번은 이렇게라도 진행해보는 것이 중요하다. ) 

 

* IDE는 통합개발툴인데, 비주얼 스튜디오, 비주얼 스튜디오 코드, 인텔리제이와 같은 것을 의미한다.

 

 

 

자 그렇다면 매번 이렇게 귀찮게 실행해야 하는가 싶지만 그렇지 않다. 우리는 환경변수를 활용해서 자바가 설치된 폴더까지 안 가더라도 언제 어디서든 사용할 수 있도록 만들어 줄 것이다. 일반적으로 환경변수는 PATH를 설정해준다고 하는데, 컴퓨터한테 자바가 어디에 설치되어 있는지 알려주는 이정표 역할을 해주는 것이다. 

 

 

 

4. 자바 환경변수 설정하기


자바 환경변수 설정에는 명령프롬프트를 활용하는 방법과 시스템 환경설정을 통해서 하는 방법이 있는데, 명령프롬프트를 이용한 방법은 명령프롬프트가 꺼지면 초기화된, 시스템 환경설정을 이용해서 진행하도록 한다.

 

제어판 -> 시스템 정보 -> 고급 시스템 설정을 클릭한다. [혹은 내 컴퓨터(내 PC) -> 오른쪽 클릭 -> 속성]

 

고급 시스템 설정을 클릭한 뒤에 -> 환경변수를 눌러준다. 

 

 

그 뒤에 새로 만들기를 눌러준다.

 

 

 

시스템 변수 편집에서 변수 이름에는 JAVA_HOME을 적어주고 변수 값에는 Java가 설치된 공간을 넣어주면 된다. 컴퓨터에게 자바가 여기에 설치되어 있다고 알려주는 것이다. 경로에 대한 변수를 할당하며, 그 변수는 JAVA_HOME이다. 대부분의 Java IDE 가 JAVA_HOME을 쓰고 있으므로 우리도 그에 따라 맞춰서 저장한다.

 

 

 

그 다음으로 Path를 입력할 것이다. 

Path를 눌러주고 편집을 누르자.

 

그러면 이렇게 나오게되는데, 

 

여기서 %JAVA_HOME%bin 을 입력해주자. 이것은 아까 저장한 JAVA_HOME이라는 변수에는 자바가 어디에 설치되어 있는지 알려주는 경로가 들어있다. 그곳에서 bin폴더가 있는 곳을 알려주는 것이다. (여기서 bin의 의미는 binary의 bin이다. 일반적으로 실행파일의 의미를 가지고 있다. 그래서 실행파일의 위치는 여기에 있다. 라고 알려준 것이다.)

 

여기까지만 해도 java는 실행이 되지만 추가적으로 classpath가 들어있다. 클래스 파일의 경로를 알려주는 것으로 환경변수로 마찬가지로 관리한다. 자동으로 등록되기도 하지만, 환경변수로 등록해보도록 하자.

 

다시 한번 새로 만들기를 누르고

CLASSPATH와 %JAVA_HOME%\lib를 등록해주자.

'\' 이 문자는 Enter 위에 존재한다. 자주 쓰이므로 잘 기억해두도록 하자.

 

자 이제 등록이 끝났다.

잘 되었는지 확인하려면 아까와 같이 명령프롬프트를 켜고! javac 혹은 java -version을 입력하면 된다. 그리고서 정상 메시지가 출력되면 설정은 완료된 것이다. 

 

자바가 설치되어 있는 곳까지 가지 않더라도 같은 메시지가 나오는 것을 확인할 수 있을 것이다.

이런식으로 D폴더에 위치하고 있어도 잘 나오는 것을 확인할 수 있다. 컴퓨터에게 경로를 잘 알려주고 있는 것이다. 

 

반응형
반응형

지난 시간에는 이미지의 출력을 간단한 예제와 함께 살펴보았다. 이번에는 입력 받아둔 이미지를 간단한 변환인 가우시안블러를 적용해보도록 하자.

 

1. 가우시안 블러 GaussianBlur()


가우시안 블러는 이미지를 부드럽게 만들어주는 필터 같은 것이다. 가우시안이나 이와 비슷한 커널을 활용해서 이미지에 담긴 정보량을 줄여준다. 이미지 처리에서는 너무 많은 정보로 인해 오히려 정보 사이의 유의미한 연결 고리를 찾기 어려울 수 있으므로 가우시안 블러를 통해 줄여주는 것이다.

 

결과부터 먼저 살펴보자.

왼쪽이 가우시안블러가 적용된 이미지, 오른쪽이 원본이미지이다. 뿌옇게 변한 것이 가우시안 블러이다. 

 

실습을 바로 해보도록 하자.

#include <opencv2/opencv.hpp>			// 헤더 파일을 가볍게 만들기 위해 교체!

using namespace cv;

int main(int argc, char** argv) {
	Mat img = imread("cat.png");
	Mat blurredImg;						//가우시안 처리가 된 이미지를 담을 변수

	if (img.empty()) 
		return -1;

	namedWindow("img", WINDOW_AUTOSIZE);		// 입력 결과를 넣을 윈도우 만들기
	namedWindow("blurredImg", WINDOW_AUTOSIZE);	// 출력 결과를 넣을 윈도우 만들기

	imshow("img", img);		

	GaussianBlur(img, blurredImg, Size(5, 5), 3,  3);
	GaussianBlur(blurredImg, blurredImg, Size(5, 5), 3, 3);

	imshow("blurredImg", blurredImg);

	waitKey(0);

	
}

지난 시간에 적용했던 코드를 활용하고 있다.

 

Mat img = imread("cat.png");

Mat blurredImg;

입력에는 img 변수를 사용하고 있으며, 출력에는 blurredImg를 선언해서 넣어주려고 한다. 여기서는 OpenCV가 자동으로 가우시안블러를 적용함으로써 줄어든 메모리를 자동으로 할당하고 메모리 크기를 조정해준다는 점이다. (간단히 우리를 편리하게 자동으로 조정/재할당 해준다.)

 

namedWindow("img", WINDOWnamedWindow("img", WINDOW_AUTOSIZE); 
namedWindow("blurredImg", WINDOW_AUTOSIZE); 

입력과 출력 결과를 넣을 윈도우를 먼저 만들어줘야 한다. 우리의 눈에 비교가 되야 어떤 부분이 달라진지 알 수 있지 않겠는가? 그래서 두 개의 윈도우 창을 만들어 준다. 

imshow("img", img);

먼저, 가우시안블러를 적용하기 전이므로 원본 이미지를 출력해준다.


GaussianBlur(img, blurredImg, Size(5, 5), 3,  3);
GaussianBlur(blurredImg, blurredImg, Size(5, 5), 3, 3);

그 다음으로 가우시안 블러를 적용해준다. 여기서는 두 번 연속으로 가우시안블러를 적용하고 있다. 1번만 해도 상관없지만 조금 더 들여다 보기 위해 2번의 가우시안 블러를 적용해보았다. 2번 째 중복된 가우시안 블러 호출은 자기 자신이 입력과 출력으로 사용되는 위에서 이야기했듯이, Mat 구조체에 해당하는 메모리가 자동으로 조정/재할당을 함으로써 메모리 사용을 최적화해준다. (아주 편리하다! 감사합니다 개발자님들)


imshow("blurredImg", blurredImg);
가우시안 블러가 완료된 것을 윈도우에 출력해준다. 


waitKey(0);

사용자 입력을 대기함으로써 마무리가 된다.

 


GaussianBlur(img, blurredImg, Size(5, 5), 3,  3);
GaussianBlur(blurredImg, blurredImg, Size(5, 5), 3, 3);

 

우리는 이 부분을 조금 더 살펴보기 위해서 코드를 조금 조정할 필요가 있다.

 

일단 코드는 이렇다.

#include <opencv2/opencv.hpp>			// 헤더 파일을 가볍게 만들기 위해 교체!

using namespace cv;

int main(int argc, char** argv) {
	Mat img = imread("cat.png");
	Mat blurredImg1, blurredImg2;						//가우시안 처리가 된 이미지를 담을 변수

	if (img.empty()) 
		return -1;

	namedWindow("img", WINDOW_AUTOSIZE);		// 입력 결과를 넣을 윈도우 만들기
	namedWindow("blurredImg1", WINDOW_AUTOSIZE);	//중간 결과를 넣을 윈도우 만들기
	namedWindow("blurredImg2", WINDOW_AUTOSIZE);	// 마지막 결과를 넣을 윈도우 만들기

	imshow("img", img);		

	GaussianBlur(img, blurredImg1, Size(5, 5), 3,  3);
	GaussianBlur(blurredImg1, blurredImg2, Size(5, 5), 3, 3);

	imshow("blurredImg1", blurredImg1);
	imshow("blurredImg2", blurredImg2);

	waitKey(0);

	
}

중간 과정을 넣을 

namedWindow("blurredImg1", WINDOW_AUTOSIZE); 를 추가했으며, 

 

imshow("blurredImg1", blurredImg1);
imshow("blurredImg2", blurredImg2);

 

확인할 수 있는 코드를 두 개 정도 더 추가해서 변화 과정을 관찰하고자 하였다.

 

다음과 같이 블러가 점진적으로 진행됨을 확인할 수 있다.

 

그렇다면 가우시안 블러의 함수 원형을 살펴보도록 하자.

 

기본 원형은

void cv::GaussianBlur( InoutArray src, OutputArray dst, Size ksize, double sigmaX, double sigmaY = 0, int borderType = BORDER_DEFAULT)

로 이루어져 있다. src는 원본 소스, dst는 출력할 소스를 의미한다. Size는 가우시안 블러를 어떤 범위로 처리할 것인지에 대한 이야기를 하고 있다. 여기서는 5×5 형태로 만들어주고 있으며, 값에 따른 결과는 한번 확인해보도록 하자.(다만 영역의 중심 픽셀에서부터 처리되므로 홀수로 처리해야 한다.)

 

가우스안블러는 수학에서 사용되는 수식을 활용하는데, 정확한 수학적 근거를 보고 싶은 사람은 이곳을 방문하자. 수학적인 해석은 차후 시간이 되면 다루도록 하겠다.

 

* 수식을 풀어서 간단히 요약해서 말하자면 사각형의 범위를 두고 그 범위에 해당하는 수치의 적당한 값으로 수치를 변경해버리는 것이다.

정확한 계산은 아니지만 이런 느낌으로 만들어버리는 것이다. 


여기서 추가로 다운 샘플링 등과 같은 복잡한 형태의 이미지 변환도 존재한다. 이는 나중에 다루도록 하겠다.

 

출처

Computer Vision: Algorithms and Applications, 2nd ed, 2021 Richard Szeliski , szeliski.org/Book/ 

docs.opencv.org/2.4/doc/tutorials/imgproc/gausian_median_blur_bilateral_filter/gausian_median_blur_bilateral_filter.html

docs.opencv.org/4.5.1/d4/d86/group__imgproc__filter.html#gaabe8c836e97159a9193fb0b11ac52cf1

 

반응형
반응형

1. 라이브러리들

OpenCV에는 다양한 라이브러리와 모듈이 존재한다. 어떤 모듈이 존재하는지는 OpenCV를 설치한 곳에 가면 볼 수 있으며, 공식 웹사이트에서도 레퍼런스를 얻을 수 있다. 어떤 모듈이 존재하는지만 머릿속에 넣어두면 이를 시기적절하게 써주면 되는 것이다. 마치 공구 상자함에 무엇이 들어있는지 알고 있다면 어떤 일을 하던지 수월하게 할 수 있을 것이다. 하지만 어떤 공구가 들어있는지 인지가 되지 않는다면 힘들게 일할 것이다. 

 

D:\opencv\sources\modules 

 

필자는 D:\에다가 opencv를 설치했으므로 이렇게 나오는 것이지만 설치한 파일에 따라서 다 다르다. 이곳에 기본적인 모듈을 확인할 수 있다.

 

 

이렇게 폴더의 형태로 존재함을 볼 수 있다. 각각의 기능을 하나하나 실행시키는 것도 좋은 일이지만, 어떻게 사용하는지 알아볼 수 있는 설명서가 있는데, 그것이 레퍼런스이다.

docs.opencv.org/4.5.1/

 

OpenCV: OpenCV modules

OpenCV  4.5.1 Open Source Computer Vision

docs.opencv.org

이곳에 가면 여러가지 모듈을 확인하고 설명서를 볼 수 있다. 자주자주 방문하는 습관을 들이자.

 

2. 헤더


opencv2/opencv.hpp에는 OpenCV의 모든 기능을 사용할 수 있도록 모든 헤더파일이 포함되어 있다. 그래서 하나만 넣어도 충분히 컴파일이 가능하다. 하지만 닭 잡는데 소 잡는 칼을 쓸 수는 없는 법이다. 물론 그래도 되지만 너무 힘들다. 헤더파일도 마찬가지이다. 너무 큰 헤더 파일은 컴파일 시간을 늘린다. 그러므로 가볍게 만들어주는 것도 중요하다. 

#include<opencv2/opencv.hpp>	// OpenCV의 기능을 사용할 수 있게 해주는 헤더파일

int main(int argc, char** argv) {
	cv::Mat img = cv::imread("cat.png");

	imshow("img", img);
	cv::waitKey(0);

	return 0;
}

이전 블로그 글에서 사용한 코드를 헤더파일만 바꾸었다. 

[Computer Science/OpenCV] - [OpenCV]OpenCV란 무엇인가? 그리고 설치

 

실제로 두개를 모두 컴파일 해보면 차이남을 알 수 있다. cv::를 사용하고 싶지 않다면 using namespace cv;를 활용하면 cv::를 붙이지 않아도 된다. 이는 C++에서 클래스 이름을 붙여주는 것이므로 컴파일러에게 사전에 알려주는 것이다. 

#include<opencv2/opencv.hpp>	// OpenCV의 기능을 사용할 수 있게 해주는 헤더파일

using namespace cv;				// namespace cv를 알려줌으로써 미리 선언해주는 역할을 한다.

int main(int argc, char** argv) {
	Mat img = imread("cat.png");

	imshow("img", img);
	waitKey(0);

	return 0;
}

여기서 헤더 파일이 너무 많은 헤더 파일을 가지고 있으므로 필요한 기능을 담고 있는 헤더파일만 포함시키면 다음과 같다.

#include"opencv2/highgui/highgui.hpp"			// 헤더 파일을 가볍게 만들기 위해 교체!

using namespace cv;

int main(int argc, char** argv) {
	Mat img = imread("cat.png");

	if (img.empty()) return -1;

	namedWindow("img", cv::WINDOW_AUTOSIZE);
	imshow("img", img);
	waitKey(0);

	destroyWindow("img");

	return 0;
}

OpenCV에는 다양한 유형의 이미지 파일을 읽을 수 있는 유틸들을 제공한다. 기본 패키지 상에 포함되어 있는 HighGUI는 이를 도와준다. 위의 코드는 HighGUI를 활용해서 이미지 파일(여기서는 cat.png)를 열고 화면 상에 출력해주는 역할을 하고 있다.

 

여기서 int argc, char** argv는 argument라하는 인수들이 저장되는 공간이 된다. argc는 argument가 몇 개인지 알려주는 것이며, argv는 char형으로 저장되는 변수인데 배열로써 저장된다. 가장 처음에 있는 argv[0]는 실행 파일명이 저장되며, 그 뒤부터 argv[1], argv[2] ....  의 순서대로 사용자가 입력한 argument가 저장된다.

 

3. 코드 해설


다음 코드를 하나씩 해설해보면서 각각의 코드가 어떤 의미를 가지고 있는지 살펴보도록 하자.

 

#include"opencv2/highgui/highgui.hpp"	

using namespace cv;

int main(int argc, char** argv) {
	Mat img = imread("cat.png");

	if (img.empty()) return -1;

	namedWindow("img", cv::WINDOW_AUTOSIZE);
	imshow("img", img);
	waitKey(0);

	destroyWindow("img");

	return 0;
}

헤더 파일은 제외하고 main 함수 내부에 있는 것들을 살펴보도록 하자.

  1. Mat img = imread ("cat.png");

  2. if(img.empty()) return -1;

  3. namedWindow("img", cv::WINDOW_AUTOSIZE);

  4. imgshow("img", img);

  5. waitKey(0);

  6. destroyWindow("img");

이런 순서대로 살펴보도록 하자. 

1. Mat img = imread ("cat.png")

먼저 나오는 imread 이다.(namespace cv가 없으면 cv::imread) image read 라고 생각하면 되는데, 파일 이름을 기반으로 파일의 포맷을 결정해준다. 예를 들어, cat.png이므로 파일 포맷 PNG에 해당하는 데이터 구조에 필요한 메모리를 자동으로 할당해주는 것이다. 이미지 파일과 관련된 다양한 포맷을 지원한다. (BMP, JPEG, JPG, PNG, DIB, PPM, TIFF 등등 다양한 이미지 포맷을 지원한다.) imread는 최종적으로 구조체 Mat의 형태로 반환한다. 

 

Mat은 구조체로써 OpenCV의 기본을 이루는 구조체라 봐도 무방할 정도로 많이 쓰이는 구조체이다. 이미지 상에 담고 있는 정보를 처리한다. 이 정보는 단일 채널, 다중 채널, 정수 값, 부동 소수 값 등으로 컴퓨터가 이미지를 받아들이는데 사용되는 다양한 데이터를 의미한다. Mat 구조체의 기본 상속은 다음과 같다.

 

조금 더 자세한 내용은 docs.opencv.org/4.5.1/d3/d63/classcv_1_1Mat.html 이곳에서 보자.

 

2. if(img.empty()) reuturn -1;

Mat구조체의 이름을 img라 정했으며, 1번에서 imread를 통해 읽어들인 cat.png 파일을 Mat이라는 구조체 변수, 이름은 img에 넣었다. 이를 통해 img.empty()는 받은 파일이 비어있는지 아닌지를 판단해주는 것이다. 반환값은 true, false로 전달해 준다. (비어있으면 true로 반환해줌, 속에 무언가 들어있으먄 false를 반환) 

 

3. namedWindow("img", cv::WINDOW_AUTOSIZE);

namedWindow 함수는 High-level GUI, HighGUI 모듈에 속하는 함수이다. 화면에 이미지를 표시할 수 있는 윈도우를 열어준다. 인수가 두 가지가 있는데, 첫번째 인수는 윈도우 이름을 지정한다. 만약에 이름이 있으면(중복되면) 아무일도 하지 않는다. 두 번째 인수는 윈도우 사이즈를 결정해주는데,

  • 윈도우 사이즈는 자동으로 이미지 크기와 같을 것인지 - WINDOW_AUTOSIZE (이미지 사이즈에 맞춰 자동 조정되며 이후에 사용자가 조정 가능하다. 하지만 윈도우 창 크기를 마우스로 늘러거나 줄이는 것은 불가능하다. 함수에 의해서 조절해야 한다.)
  • 이미지 사이즈 관계없이 동일한 값으로 만들 것인지 - 0 (기본값이다.), 처음에 만들어진 값은 고정 값으로 만들어지지만, 마우스를 통해 늘리거나 줄이는 것이 가능하다.

두 번째 인수에 들어갈 flag값은 여기에서 확인이 가능하다. 

HighGUI는 4가지의 주요한 함수가 존재하는데, ButtonCallback, MouseCallBack, OpenGIDrawCallback, TrackbarCallback으로 차례대로 버튼, 마우스, 화면 출력, 트랙바에 해당하는 값을 담당한다. [opencv2/highgui.hpp 헤더에 들어있다.] 기본으로 제공된 함수 외 더 많은 기능을 사용하고자 한다면 Qt 를 활용해서 확장해나가면 된다. Qt는 C++을 통해 GUI를 제작하는 크로스플랫폼 프레임워크이다. (C++외에 다른 언어로도 만들 수 있다.) 자동차 계기판 GUI부터 시작해서 스마트 Tv에 들어가는 GUI까지 다양하게 만들어져있다. 

Qt를 더 알고 싶다면 -> www.qt.io/ko-kr/

 

Qt | 임베디드와 데스크탑을 위한 크로스플랫폼 소프트웨어 개발

Qt는 혁신적인 기기와 세련된 UI 및 어플리케이션을 만드는 빠르고, 스마트한 방법입니다. 우수한 크로스플랫폼 소프트웨어 개발을 만나보세요.

www.qt.io

 

4. imgshow("img", img);

Mat구조체 상에 이미지에 대한 정보가 들어있다면 imgshow를 통해 화면에 출력할 수 있다. (조금 더 정확히는 위에서 만든 윈도우에 출력할 수 있다. 만약에 만들어진 윈도우가 없다면 cv::imshow함수는 cv::namedWindow()를 활용해서 새롭게 생성한다. ) 실제로 보여주는 역할을 하게 해주는 함수이다.

 

5. waitKey(0);

waitKey(0); 의 기본 원형 int cv::waitKey ( int delay = 0 ) 의 원형을 가지고 있으며, 키 입력이 있을 때까지 기다리는 함수이다. 인수는 밀리세컨드 단위로 대기하는 것이다. 0 또는 음수로 설정이 될 경우에, 키 입력을 무한히 기다리는 형태이다. (항상 조심해야 하는 것은 시간의 단위가 밀리세컨드 단위라는 점이다! - millisecond는 1000 분의 1초이다. 0.5초라면 500 millisecond)

 

6. destroyWindow("img");

OpenCV는 메모리 사용에 대해서 많은 고려가 되었는데, destroyWindw 또한 메모리 해제와 관련된 함수이다. 일반적으로 표준 템플릿 라이브러리(STL)의 스코프 밖으로 벗어나게 되면 자동으로 메모리 할당이 해제 되지만, 규모가 조금이라도 커진다면 프로그래머가 임의로 해제해줘야 하는 상황이 발생할 수도 있다. destroyWindow는 윈도우를 닫고 관련된 모든 메모리 사용에 대해 해제하는 역할을 해준다. (메모리 누수를 방지하기 위해 중요한 역할을 한다.) 위의 코드 상에는 사실 필요가 없지만, 이러한 것이 있다라는 것을 보여주기 위해 넣어두었다.

 

 

반응형

+ Recent posts