본문 바로가기
Studynote/Computer Science 12

Chapter_02_3_IplImage 영상 자료구조

by e.sunie 2018. 11. 3.

Chapter 02. OpenCV C API 자료구조


3.IplImage 영상 자료 구조


(1) IplImage 자료형

OpenCV에서 2차원 영상을 위한 자료구조

typedefstructIplImage

{

intnSize;

intID;

intnChannels;

intalphaChannel;

intdepth;

charcolorMode[4];

charchannelSeq[4];

intdataOrder;

intorigin;

intalign;

intwidth;

intheight;

struct_IplROI *roi;

struct_IplImage *maskROI;

void*imageId;

struct_IplTileInfo *tileInfo;

intimageSize;

char*imageData;

intwidthStep;

intBorderMode[4];

intBorderConst[4];

char*imageDataOrigin;

}IplImage;


  • intnChannels : 채널의 개수 , 1-4 정수

  • intdepth : 화소의 비트 표현

    depth

    설 명

    IPL_DEPTH_8U

    8비트 unsigned 정수

    IPL_DEPTH_8S

    8비트 signed 정수

    IPL_DEPTH_16U

    16비트 unsigned 정수

    IPL_DEPTH_16S

    16비트 signed 정수

    IPL_DEPTH_32S

    32비트 signed 정수

    IPL_DEPTH_32F

    32비트 단정도 실수

    IPL_DEPTH_64F

    64비트 배정도 실수

  • intdataOrder : 채널 자료의 저장 순서

dataOrder=0 : 인터리브 컬러 채널 ~ 각 화소의 채널 값이 RGR이 채널 순서대로 저장

dataOrder=1 : 분리 컬러 채널 ~ 한 채널의 모든 화소 저장 다음 그 다음 채널 순으로 컬러값 저장

  • intorigin : 영상의 원점 정의

origin=0 : 왼쪽 상단이 원점 (묵시적 원점 )

origin=1 : 외쪽 하단이 원점

  • intwidth : 영상의 가로 방향 화소 수 intheight : 영상의 세로 방향 화소 수

  • struct_IplROI *roi : Region Of Interest(ROI)로 영상에서 관심 영역

typedefstruct_IplROI

{

/*

0 : no COI (all channels are selected)

1 : 0th channel is selected ...

*/

intcoi;

intxOffset;

intyOffset;

intwidth;

intheight;

}IplROI;

  • intwidthStep 한 행의 바이트 개수



(2) 파일에서 영상 읽기 및 화면에서 출력하기


  • IplImage* cvLoadImage(const char* filename, int iscolor=CV_LOAD_IMAGE_COLOR);

filename 파일에서 영상을 읽어오는 함수

iscolor : 영상의 컬러 지정 인수

CV_LOAD_IMAGE_COLOR : 3채널 영상

    • CV_LOAD_IMAGE_GRAYSCALE : 1채널 그레이 스케일 영상

    • CV_LOAD_IMAGE_UNCHANGED : 원본 영상 그대로

영상 포맷 : 윈도우즈 비트맵 (BMP,DIB) ,JPEG, PNG, TIFF 등


  • int cvSaveImage(const char* filename, const CvArr* image);

영상을 파일에 저장

영상 포맷 : 파일의 확장자에 의해 정해진다 .

8비트 단일 채널 & 3채널 컬러영상으로 저장가능


  • int cvWaitKey(int delay=0);

delay/100초 만큼 지연 대기한다 .

Delay=0 : 무한 대기 (키를 누를 때까지 )


  • int cvNamedWindow(const char* name, int flags);

name을 윈도우 캡션으로 사용하는 윈도우 생성

name은 윈도 식별 ID로 사용

flags = CV_WINDOW_AUTOSIZE : 윈도우 크기를 영상 크기에 자동 조절


  • void cvDestoryWindow(const char* name);

cvNamedWindow에 의해 생성된 윈도우 파괴

cvDestoryAllWindow(void)함수 : 생성 윈도우가 하나 이상일 떄 한번에 파괴 가능


  • void cvShowImage(const char* name, const CvArr* image);

name이름을 갖는 윈도우에 영상 image를 보여준다 .

영상크기에 맞게 윈도우 크기가 스케일됨


영상을 파일에 불러와서 화면에 출력

#include<iostream>

#include<opencv2/opencv.hpp>

#include<opencv2/highgui/highgui.hpp>


intmain()

{

IplImage*srcImage;

if( (srcImage =cvLoadImage("lena.jpg")) ==NULL)

//if((srcImage=cvLoadImage("lena.jpg",CV_LOAD_IMAGE_GRAYSCALE))==NULL)

return-1;

printf("colorModel = %s \n", srcImage->colorModel);

printf("channelSeq = %s \n", srcImage->channelSeq);

printf("image pixel size = %d x %d \n", srcImage->width, srcImage->height);

printf("# of channel = %d \n", srcImage->nChannels);

printf("depth = %d \n", srcImage->depth);

cvNamedWindow("Lena",CV_WINDOW_AUTOSIZE);

cvShowImage("Lena", srcImage);

cvWaitKey(0);

cvDestroyWindow("Lena");

cvReleaseImage(&srcImage);

return0;

}


교재와 다름

결과값 자체가 출력 안됨ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠ

lena파일은 프로젝트파일에 넣어둠

은선 추측 : 걍 return -1 당한듯



(3)IplImage 영상 생성 및 파괴


영상의 화소의 값을 가져오고 (get/read), 변경 (set/wirte)하는 방법

: 행렬 (CvMat)에서 설명한 함수 사용


  • IplImage* cvCreateImage(CvSize size, int depth, int channels);

    • size, width, height, depth, channels를 이용하여 영상의 IplImage 해더를 생성 &영상 데이터를 위한 메모리 할당

~ 인터리브 채널 영상을 생성

 

 

  • 영상의 IplImage 해더를 생성한다 = IplImage 구조체의 맴버 변수를 초기화한다 .
  • cvCreateImageHeader함수 호출하고 , cvCreateData함수를 호출한 것과 동일
  • 입력 영상에 대한 중간 결과 또는 최종 결과 영상을 위한 메모리 할당에 주로 사용

 

 

IplImage* header = cvCreateImageHeader(size, depth, channels);

cvCreateData(header);


  • IplImage* cvCreateImageHeader(CvSize size, int depth, int channels);

영상의 IplImage해더는 생성 but 영상 데이터를 위한 메모리 할당 안함


  • void cvReleaseImage(IplImage** image)

이미지의 헤더와 영상을 위해 할당된 메모리 해제


  • void cvReleaseImageHeader(IplImage** image);

이미지의 해더를 위한 메모리만 해제


  • IplImage* cvInitImageHeader(IplImage* image, CvSize size, int depth, int channels, int origin=0, int align=4);

이미 생성된 영상 image의 헤더를 size, depth, channels, origin,align을 사용하여 초기화한 후 포인터 반환


  • IplImage* cvCloneImage(const IplImage* image);

영상의 헤더 , 데이터 , ROI 모두 복수 &다음 영상 포인터 반환


  • CV_IMAGE_ELEM 매크로 함수

매크로 함수를 사용하여 영상의 화소에 접근


영상 생성 및 파괴

#include<iostream>

#include<opencv2/opencv.hpp>

#include<opencv2/highgui/highgui.hpp>


intmain()

{

intx, y;

IplImage*srcImage;

srcImage =cvCreateImage(cvSize(512,512),IPL_DEPTH_8U,1);

/*

for(y= 0; y<srcImage->height; y++)

for(x= 0; x<srcImage->width; x++)

{

cvSetReal2D(srcImage, y, x, 255); // white

}

*/

cvSet(srcImage,cvScalar(255));

for(y=200; y<300; y++)

for(x=200; x<300; x++)

{

cvSetReal2D(srcImage, y, x,0);// black

}

cvNamedWindow("srcImage",CV_WINDOW_AUTOSIZE);

cvShowImage("srcImage", srcImage);

cvWaitKey(0);

cvDestroyWindow("srcImage");

cvReleaseImage(&srcImage);

return0;

}



CV_IMAGE_ELEM 매크로를 이용한 영상 복사

#include<iostream>

#include<opencv2/opencv.hpp>

#include<opencv2/highgui/highgui.hpp>


intmain()

{

intx, y, k;

IplImage*srcImage;

if( (srcImage =cvLoadImage("lena.jpg")) ==NULL)

// if((srcImage=cvLoadImage("lena.jpg",CV_LOAD_IMAGE_GRAYSCALE))==NULL )

return-1;

IplImage*dstImage =cvCreateImage(cvGetSize(srcImage),

srcImage->depth, srcImage->nChannels);

// copy srcImage to dstImage

for(y=0; y<srcImage->height; y++)

for(x=0; x<srcImage->width; x++)

{

uchar*src=&CV_IMAGE_ELEM(srcImage,uchar,

y, x*(srcImage->nChannels));

for( k=0; k<srcImage->nChannels; k++)

{

CV_IMAGE_ELEM(dstImage,uchar,

y, x*(srcImage->nChannels) + k ) = src[k];

}

}

/*

for(y= 0; y<srcImage->height; y++)

for(x= 0; x<srcImage->width*srcImage->nChannels; x+=srcImage->nChannels)

{

uchar *src = &CV_IMAGE_ELEM(srcImage, uchar,y, x);

for( k=0; k<srcImage->nChannels; k++)

{

CV_IMAGE_ELEM(dstImage, uchar, y, x+k ) = src[k];

}

}

*/

cvNamedWindow("srcImage",CV_WINDOW_AUTOSIZE);

cvShowImage("srcImage", srcImage);

cvNamedWindow("dstImage",CV_WINDOW_AUTOSIZE);

cvShowImage("dstImage", dstImage);

cvWaitKey(0);

cvDestroyAllWindows();

cvReleaseImage(&srcImage);

cvReleaseImage(&dstImage);

return0;

}

Program ended with exit code: 255


ImageData 포인터를 이용한 직접 영상 복사

#include<iostream>

#include<opencv2/opencv.hpp>

#include<opencv2/highgui/highgui.hpp>

intmain()

{

intx, y, k;

IplImage*srcImage;

if( (srcImage =cvLoadImage("lena.jpg")) ==NULL)

// if((srcImage=cvLoadImage("lena.jpg",CV_LOAD_IMAGE_GRAYSCALE))==NULL )

return-1;

IplImage*dstImage =cvCreateImage(cvGetSize(srcImage),

srcImage->depth, srcImage->nChannels);

// copy srcImage to dstImage

for(y=0; y<srcImage->height; y++)

for(x=0; x<srcImage->width; x++)

{

intindex = (y*srcImage->widthStep+ x*(srcImage->nChannels));

// int index = (y*dstImage->widthStep + x*(dstImage->nChannels));

uchar*src = (uchar*)(srcImage->imageData+ index);

uchar*dst = (uchar*)(dstImage->imageData+ index);

for( k=0; k<srcImage->nChannels; k++)

{

dst[k] = src[k];

}

}

cvNamedWindow("srcImage",CV_WINDOW_AUTOSIZE);

cvShowImage("srcImage", srcImage);

cvNamedWindow("dstImage",CV_WINDOW_AUTOSIZE);

cvShowImage("dstImage", dstImage);

cvWaitKey(0);

cvDestroyAllWindows();

cvReleaseImage(&srcImage);

cvReleaseImage(&dstImage);

return0;

}

Program ended with exit code: 255



댓글