OpenCV 요약 정리(자주쓰는 기능)

IplImage 생성

1
2
3
4
// 생성
IplImage *srcimg_R = NULL;
srcimg_R = cvCreateImage(cvSize(m_width,m_height), 8, 3); // cvSize(640,480) 같은 것도 됨
srcimg_R = cvCreateImage(cvGetSize(src_color), 8,3)// 다른 IplImage 사이즈 받아와서

1
2
3
4
5
// 이 방법도 사용 가능
CvSize img_size; 
img_size.height = ImageHeight;
img_size.width = ImageWidth;
IplImage* BGR_image = cvCreateImage(img_size, IPL_DEPTH_8U, 3)


이미지 복사하기

1
2
src = cvCloneImage(src_img)// src가 비어있어야 함. 데이터가 있으면 메모리 계속 쌓인다.
cvCopy(src_img, src_img2);


컬러 이미지 각 채널별 분리 및 결합

1
2
cvCvtPixToPlane( src_hlsimg, Hue, Intensity, Saturation, NULL )// HLS 이미지 각 속성별로 나눔
cvCvtPlaneToPix( Hue, Intensity, Saturation, NULL, Equ_hls )// 다시 합친다


IplImage 이미지 데이터 0초기화(검정 이미지)

1
cvZero(src_img);


IplImage 해제

1
2
if(srcimg_R)
   cvReleaseImage(&srcimg_R);


IplImageROI 설정하기

1
2
3
4
5
//설정한 ROI 부분을 전체 이미지 인 것처럼 다룬다
//cvSetImageROI( IplImage* img, CvRect rect )
//rect는 순서대로 ROI의 왼쪽 위점의 좌표, ROI의 width, height이다.
 
cvSetImageROI(src, cvRect(CenterX-ROI_width/2, CenterY-ROI_height/2, ROI_width, ROI_height));

설정한 ROI 해제하기

1
cvResetImageROI( IplImage* img );


1
2
3
4
5
6
7
8
//ROI가 설정되어 있다면
if(inputimg->roi != 0x00)
{
    //ROI의 속성 접근하기
    inputimg->roi->width 
    inputimg->roi->height
    ...
}


이미지 불러오기, 저장하기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//불러오기 1
Img = cvLoadImage("AndroidImage.bmp"); // Img 구조체에 AndroidImage.bmp를 load
 
//불러오기 2
if ((Img = cvLoadImage("AndroidImage.bmp")) == 0) // load image
{
   printf("%s", "image file read has failed!! \n");
   return 0;
}
 
//저장하기
char file_name[20];
sprintf(file_name,"WriteImage.bmp")//파일이름 만들기
cvSaveImage(file_name,srcimg_R)//srcimg_R 이라는 IplImage를 저장 



이미지 위 아래나 좌우 뒤집기, 반전

1
cvFlip(src, dst, 0)//0은 수직방향 반전, 1은 수평방향 반전, -1은 양방향 다 반전



카메라로 부터 입력받기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
IplImage *src; 
 
//capture for cam
CvCapture* capture = cvCaptureFromCAM(0); // 0번 카메라로부터 입력받음
 
//get init scene
src=cvRetrieveFrame(capture); //src에 capture된 이미지 담기
 
....
// 처리
....
 
//해제
cvReleaseCapture( &capture );


동영상으로 부터 입력받기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
CvCapture* input_video = 0;
input_video = cvCreateFileCapture( "movie.avi");
 
//받아온 프레임 사이즈
CvSize frame_size;
int height =(int) cvGetCaptureProperty( input_video, CV_CAP_PROP_FRAME_HEIGHT );
int width =(int) cvGetCaptureProperty( input_video, CV_CAP_PROP_FRAME_WIDTH );
int fps =(int) cvGetCaptureProperty(input_video, CV_CAP_PROP_FPS);
printf("width : %d, height : %d, fps : %d\n", width, height, fps)
 
//연산에 사용될 IplImage 구조체
IplImage *src;
 
if( (src=cvQueryFrame(input_video)) != 0)
{
   printf("file read success!!\n");
}
 
while(1)
{
   src=cvQueryFrame(input_video)
}
 
cvReleaseCapture( &input_video );


윈도우 생성 및 파괴

1
2
3
4
5
6
7
8
9
10
11
12
13
//생성
cvNamedWindow("Right Original", CV_WINDOW_AUTOSIZE);
 
//창 움직이기
cvMoveWindow("source_color",610,0);
 
//보이기
cvShowImage( "Right Original", srcimg_R );
 
//창 닫기
cvDestroyAllWindows();  //모든 OpenCV 윈도우 닫기
 
cvDestroyWindow("Right Original"); //특정 윈도우만 닫기



창으로 부터 키 입력 받기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
pressed_key=cvWaitKey(0);
 
if(pressed_key=='q'//q 키가 누르면 빠져나가기
    break;
else if(pressed_key=='c'//캡쳐 키 누르면 캡쳐
{
   timer=time(NULL)//현재시간저장
   t=localtime(&timer)//지역시간
   sprintf(file_name,"img_%4d%02d%02d%02d%02d%2d.bmp",t->tm_year + 1900, 
            t->tm_mon +1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec)//파일이름 만들기
   cvSaveImage(file_name, src_color);
 
   printf("%s file saved is success!!\n",file_name);  //확인메시지 출력
}



이미지 크기 줄이기

1
2
3
4
5
6
7
//생성
pEviMonitor = cvCreateImage(cvSize(m_pImgWidth, m_pImgHeight), IPL_DEPTH_8U, 1);
pEviMonitor2 = cvCreateImage(cvSize(m_pImgWidth/2, m_pImgHeight/2), IPL_DEPTH_8U, 1)
 
// 1/2 크기로 생성
// 크기 줄이기
cvResize(pEviMonitor, pEviMonitor2, CV_INTER_LINEAR)//Resize



화면에 글자 쓰기

1
2
3
4
5
6
7
char s_output_result[50];
CvFont font;
 
sprintf(s_output_result,"sum vector x:%1.3f y:%1.3f",sumvector_x,sumvector_y )//우선 sprintf로 문자열 생성
cvInitFont(&font, CV_FONT_HERSHEY_SIMPLEX|CV_FONT_ITALIC, 0.5, 0.5, 0, 1); // font 초기화
 
cvPutText(src_color, s_output_result ,cvPoint(15,20),&font,cvScalar(0,255,0))//cvPoint로 글자 시작 위치 설정


트랙바 생성

1
2
3
4
int hue_threshold=139; //Hue 값의 피부색 threshold
 
cvNamedWindow( "HLS_image", CV_WINDOW_AUTOSIZE );
cvCreateTrackbar("Hue","HLS_image",&hue_threshold,255, NULL );


마우스 입력

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void on_mouse( int event, int x, int y, int flags, void* param );
 
......
cvSetMouseCallback( "LKTracker", on_mouse, NULL );
......
 
void on_mouse( int event, int x, int y, int flags, void* param )
{
   if( !image )
      return;
    
   if( image->origin )
      y = image->height - y;
    
   if( event == CV_EVENT_LBUTTONDOWN )
   {
      pt = cvPoint(x,y);
      add_remove_pt = 1;
   }
}

canny edge detect 사용하기

1
2
3
4
5
6
IplImage *canny_R = NULL;
canny_R = cvCreateImage(cvSize(m_width,m_height), 8, 1);
 
cvCvtColor(srcimg_R, grayimg_R, CV_BGR2GRAY)//원본 컬러이미지를 흑백으로 변환하고
 
cvCanny( grayimg_R, canny_R, 40, 130, 3 )//그 흑백이미지를 캐니로 변환



Harris edge detector 사용하기

1
2
IplImage *harris = cvCreateImage(cvSize(WIDTH,HEIGHT), IPL_DEPTH_32F, 1);
cvCornerHarris(src_gray, harris, 3, 9, 0.07)



Smoothing 연산

1
2
3
4
5
6
7
//Gaussian filtering
cvSmooth(src, Gaussed_image, CV_GAUSSIAN, 3)
 
//DoG(Difference of Gaussian)
cvSmooth(src_gray, GaussImg1, CV_GAUSSIAN, 3);
cvSmooth(src_gray, GaussImg2, CV_GAUSSIAN, 27);
cvSub(GaussImg1, GaussImg2, dst);



HLS 이미지로 변환하기

1
2
3
4
5
6
7
8
9
10
11
//HLS 이미지
IplImage* src_hlsimg = cvCreateImage(cvSize(m_width,m_height), 8, 3)
 
//각 속성들 저장할 곳 선언
IplImage* Hue = cvCreateImage(cvSize(m_width,m_height), 8, 1);
IplImage* Intensity = cvCreateImage(cvSize(m_width,m_height), 8, 1);
IplImage* Saturation = cvCreateImage(cvSize(m_width,m_height), 8, 1);
 
cvCvtColor(srcimg, src_hlsimg, CV_BGR2HLS)//src_hlsimg IplImage 구조체에 HLS 이미지 담긴다
cvCvtPixToPlane( src_hlsimg, Hue, Intensity, Saturation, NULL )//HLS 이미지 각 속성별로 나눔
cvCvtPlaneToPix( Hue, Intensity, Saturation, NULL, hsvVideo2 )//도로 합치기



모폴로지 연산 Morphology

1
2
3
IplConvKernel* kernel;
kernel= cvCreateStructuringElementEx( 3, 3, 0, 0, CV_SHAPE_RECT, NULL );
cvMorphologyEx( temp_eyeimg, temp_eyeimg, NULL,kernel, CV_MOP_CLOSE , 1 );



히스토그램 관련

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
CvHistogram* hist;
float min_value, max_value; //히스토그램 최대값 최소값 저장
int hist_size = 255; //히스토그램 축 개수
 
hist = cvCreateHist( 1, &hist_size, CV_HIST_UNIFORM)//1차원의, 각 속성 크기 hist_size인 히스토그램 생성
cvCalcHist( &Hue, hist, 0, 0)//Hue가 1차원 IplImage -> 실질적 입력
cvGetMinMaxHistValue(hist, &min_value, &max_value, 0, 0)//히스토그램 최소최대값 얻기, 최대최소값의 위치
printf("hist min max:%f %f\n",min_value, max_value);
 
cvZero(Hue_hist);
 
int axis_base = 210; //그릴 때, 아래 축이 어느정도에 위치하는가
CvFont font; //축에 글자 쓰기
cvInitFont(&font, CV_FONT_HERSHEY_SIMPLEX|CV_FONT_ITALIC, 0.3, 0.3, 0, 1);
char text[50];
 
for ( int i = 0; i <255; ++i)
{   
    int hist_value = cvRound(cvQueryHistValue_1D(hist,i)*255/max_value)//히스토그램 값 normalization
    cvLine(Hue_hist, cvPoint(i+20, axis_base), cvPoint(i+20, abs(axis_base - hist_value) ), CV_RGB(255,255,255), 1);
    
    if ((i % 20) == 0 )
    {
       sprintf( text, "%d", i);
       cvPutText( Hue_hist, text, cvPoint(i+20, axis_base+10), &font, CV_RGB(255,255,255))
    }
}
 
if(hist) //히스토그램 제거
   cvReleaseHist(&hist);
 


히스토그램 평활화 (histogram equalization)

1
2
3
IplImage* Src = cvCreateImage(cvSize(width,height), 8, 1)//원본 이미지
IplImage* Equalized = cvCreateImage(cvSize(width,height), 8, 1)//평활화 된 이미지
cvEqualizeHist( Src, Equalized );


이미지 회전시키기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
CvPoint2D32f rot_center = cvPoint2D32f(ROI_width/2 , ROI_height/2); //회전중심설정
 
// 회전 매트릭스 만들기
CvMat *rot_mat = cvCreateMat( 2, 3, CV_32FC1);
 
//매트릭스 계산 
cv2DRotationMatrix( 
      rot_center, //Source Image의 센터
      Rotation_Angle, //각도 + 값은 시계 반대 반대 방향을 의미
      1, // 이미지 크기(scale)... 
      rot_mat); // 결과를 저장하는 매트릭스
      
//원본 이미지에 ROI 적용하기
cvSetImageROI(src, cvRect(CenterX-ROI_width/2, CenterY-ROI_height/2, CenterX+ROI_width/2, CenterY+ROI_height/2));
 
//변환하기
cvWarpAffine(src, dst, rot_mat, CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS,cvScalarAll(0)); // 선형보간