OpenCV 학습 노트 (2) - IplImage 데이터 구조

7708 단어
IplImage 구 조 는 다음 과 같이 정확하게 정의 합 니 다.
typedef struct _IplImage
{
    int  nSize;             /* sizeof(IplImage) */
    int  ID;                /* version (=0)*/
    int  nChannels;         /* Most of OpenCV functions support 1,2,3 or 4 channels */
    int  alphaChannel;      /* Ignored by OpenCV */
    int  depth;             /* Pixel depth in bits: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16S,
                               IPL_DEPTH_32S, IPL_DEPTH_32F and IPL_DEPTH_64F are supported.  */
    char colorModel[4];     /* Ignored by OpenCV */
    char channelSeq[4];     /* ditto */
    int  dataOrder;         /* 0 - interleaved color channels, 1 - separate color channels.
                               cvCreateImage can only create interleaved images */
    int  origin;            /* 0 - top-left origin,
                               1 - bottom-left origin (Windows bitmaps style).  */
    int  align;             /* Alignment of image rows (4 or 8).
                               OpenCV ignores it and uses widthStep instead.    */
    int  width;             /* Image width in pixels.                           */
    int  height;            /* Image height in pixels.                          */
    struct _IplROI *roi;    /* Image ROI. If NULL, the whole image is selected. */
    struct _IplImage *maskROI;      /* Must be NULL. */
    void  *imageId;                 /* "           " */
    struct _IplTileInfo *tileInfo;  /* "           " */
    int  imageSize;         /* Image data size in bytes
                               (==image->height*image->widthStep
                               in case of interleaved data)*/
    char *imageData;        /* Pointer to aligned image data.         */
    int  widthStep;         /* Size of aligned image row in bytes.    */
    int  BorderMode[4];     /* Ignored by OpenCV.                     */
    int  BorderConst[4];    /* Ditto.                                 */
    char *imageDataOrigin;  /* Pointer to very origin of image data
                               (not necessarily aligned) -
                               needed for correct deallocation */
}
IplImage;

width 와 height 라 는 두 변 수 는 매우 중요 합 니 다. 그 다음은 depth 와 nchannals. depth 변수의 값 은 행렬 에서 보 이 는 대응 변수 와 다 릅 니 다. 그림 에서 우 리 는 깊이 와 채널 수 를 분리 하여 처리 하기 때 문 입 니 다. 행렬 에서 우 리 는 그들 을 동시에 표시 합 니 다.
depth 사용 가능 한 값 은:
IPL_DEPTH_8U, 부호 없 는 8 비트 정수 (8u)
 IPL_DEPTH_8S, 기호 8 비트 정수 (8s)
 IPL_DEPTH_16S, 기호 16 비트 정수 (16s)
IPL_DEPTH_32S, 기호 32 비트 정수 (32s)
 IPL_DEPTH_32F, 32 비트 부동 소수점 단일 정밀도 (32f)
 IPL_DEPTH_64F. 64 는 부동 소수점 더 블 정밀도 (64f)
채널 수 nChannel 에서 취 할 수 있 는 값 은 1, 2, 3 또는 4 입 니 다.
이 어 두 명의 중요 멤버 는 Origin 과 dataOrder 였 다.
origin 변 수 는 두 가지 수치 가 있 습 니 다: IPLORIGIN_TL 과 IPLORIGIN_BL, 좌표 원점 의 위 치 를 각각 설정 하여 그림 왼쪽 상단 또는 왼쪽 하단 에 배치 합 니 다.
컴퓨터 시각 분야 에서 중요 한 오 류 는 원점 위치의 정의 가 일치 하지 않 는 것 이다. 구체 적 으로 말 하면 이미지 의 소스 운영 체제, 인 코딩 디코더 와 저장 형식 등 요소 가 이미지 좌표 원점 의 선택 에 영향 을 줄 수 있다. 예 를 들 어 이미지 위의 얼굴 부분 에서 표본 을 추출 하고 있다 고 생각 할 수도 있 지만 사실은 이미지 아래 의 치마 에서 표본 을 추출 하고 있다.이러한 현상 이 반생 하지 않도록 하 는 가장 좋 은 방법 은 처음에 시스템 을 검 측 하고 이미지 블록 을 조작 하 는 곳 에 물건 을 그 려 보 는 것 이다.
dataOrder 의 수 치 는 IPL 일 수 있 습 니 다.DATA_ORDER_PIXEL 또는 IPLDATA_ORDER_PLANE. 전 자 는 데 이 터 를 픽 셀 점 의 서로 다른 채널 의 값 을 교차 시 켜 배열 하 는 것 이 라 고 밝 혔 다. 후 자 는 모든 픽 셀 을 채널 값 과 함께 배열 하여 채널 평면 을 형성 한 다음 에 평면 을 배열 하 는 것 이다.
매개 변수 widthStep 는 CvMat 의 step 매개 변수 와 유사 합 니 다. 인접 한 같은 열 점 간 의 바이트 수 를 포함 합 니 다. width 만 으로 는 이 값 을 계산 할 수 없습니다. 처리 과정 이 더욱 효율 적 이기 때문에 줄 마다 고정된 바이트 수로 정렬 합 니 다.따라서 i 줄 끝 과 i + 1 줄 의 시작 부분 에 불필요 한 바이트 가 있 을 수 있 습 니 다.
매개 변수 imageData 는 첫 번 째 줄 의 그림 을 가리 키 는 지침 을 포함 합 니 다. 그림 에 독립 된 평면 이 있다 면 그들 을 단독 이미지 로 연속 적 으로 배치 합 니 다. 전체 줄 수 는 height 와 nChannel 의 곱 입 니 다. 그러나 일반적인 상황 에서 그들 은 교차 되 어 줄 수 를 높이 와 같 게 하고 줄 마다 교차 하 는 통 로 를 질서 있 게 포함 합 니 다.
마지막 으로 중요 한 매개 변수 인 관심 분야 (ROI) 가 있 습 니 다. 실제로 그 는 또 다른 IPL / IPP 구조 인 IplRoI 의 인 스 턴 스 입 니 다. IPlroi 는 x Offset, yOffet, height 와 width 와 coi 구성원 변 수 를 포함 합 니 다. 그 중에서 COI 는 Channel of inter (관심 있 는 채널) 를 대표 합 니 다. ROI 의 사상 은 ROI 를 설정 하면전체 그림 에 사용 되 는 채널 의 함수 변 화 는 ROI 잠 금 이 표시 하 는 하위 그림 만 작 동 합 니 다. IPImage 변수 에 ROI 가 설정 되 어 있 으 면 모든 OpenCV 함수 가 이 ROI 변 수 를 사용 합 니 다. COI 가 0 으로 설정 되 어 있 으 면 이 그림 의 동작 은 지 정 된 채널 에 만 작 동 합 니 다. 불행 하 게 도 많은 OpenCV 함수 들 이 매개 변수 COI 를 무시 합 니 다.
접근 이미지 데이터
OpenCV 에는 대부분의 이미지 처리 작업 을 수행 하 는 데 도움 이 되 는 최적화 함수 가 많 지만 라 이브 러 리 에 미리 포 장 된 함수 가 없 으 면 해결 할 수 있 습 니 다. 예 를 들 어 3 채널 HSV 이미지 가 있 으 면 색도 가 변 하지 않 는 상황 에서 우 리 는 각 점 의 포화 도와 높이 를 255 로 설정 해 야 합 니 다. 우 리 는 포인터 로 그림 을 옮 겨 다 닐 수 있 습 니 다.
void statrate_sv( IplImage* img)
{
	for(int y = 0 ; y < img->height; y++)
	{
		uchar* ptr = (uchar*)(img->imageData + y * img->widthStep);
	
		for (int x= 0;x < img ->width ;x++)
		{
			ptr[3*x + 1] = 255;
			ptr[3*x + 2] = 255;
		}
	}
}

위의 프로그램 에서, 우 리 는 포인터 ptr 로 y 줄 의 시작 위 치 를 가리 키 고 있 습 니 다. 이 어, 우 리 는 포인터 에서 포화 도와 높이 가 x 차원 에 있 는 값 을 분석 합 니 다. 이것 은 3 채널 이미지 이기 때문에, c 채널 은 x 줄 의 위치 가 3 * x + c 입 니 다.
CvMat 의 구성원 data 에 비해 IpImage 와 CvMat 사이 의 중요 한 차이 점 은 imageData. CvMat 의 data 가 연합 형식 이기 때문에 지침 을 사용 해 야 하 는 유형 을 설명해 야 합 니 다. imageData 지침 은 바이트 형 지침 (unchar *) 입 니 다. 우 리 는 이러한 유형의 지침 이 unchar 형식 을 가리 키 는 것 을 이미 알 고 있 습 니 다. 이것 은 이미지 에서 지침 연산 을 할 때실제 데이터 형식 에 신경 쓰 지 않 고 widthstep (바이트 단위) 를 간단하게 늘 릴 수 있 습 니 다.
행렬 을 처리 하려 면 데이터 포인터 가 비 바이트 형식 일 수 있 기 때문에 오프셋 을 하고 조정 해 야 합 니 다.데이터 포인터 가 항상 바이트 형식 을 가리 키 기 때문에 그림 을 처리 할 때 오프셋 을 직접 사용 할 수 있 습 니 다.
ROI 와 widthStep 에 대한 보충
OpenCV 에 서 는 ROI 와 widthStep 를 보편적으로 지원 합 니 다. 함수 의 조작 은 관심 있 는 영역 으로 제한 되 어 있 습 니 다. ROI 를 설정 하거나 취소 하려 면 cvsetImageROI () 와 cvResetImage () 함 수 를 사용 해 야 합 니 다. ROI 를 설정 하려 면 함수 cvsetImageROI () 를 사용 하여 이미지 포인터 와 사각형 을 전달 할 수 있 습 니 다. ROI 를 취소 하려 면 함수 cvResetImageROI () 에 이미지 포인 터 를 전달 해 야 합 니 다.
void  cvSetImageROI( IplImage* image, CvRect rect );
void  cvResetImageROI( IplImage* image );
예 를 들 어 3.12. 그림 을 읽 고 원 하 는 ROI 의 x, y, width, height 의 값 을 설정 합 니 다. 마지막 으로 ROI 구역 에 정 수 를 추가 합 니 다. 이 규칙 에서 내 연 된 cvRrect () 구조 함수 로 ROI 를 설정 합 니 다. cvReset IMageROI () 함 수 를 통 해 ROI 를 방출 하 는 것 이 중요 하지 않 습 니 다. 그렇지 않 으 면 ROI 구역 을 충 실 히 표시 합 니 다.
// 3.12  imageROI         
#include "stdafx.h"
#include <cv.h>
#include <highgui.h>
int _tmain(int argc, _TCHAR* argv[])
{
	IplImage* src;
	src = cvLoadImage("C:/Users/Administrator/Desktop/lena.bmp");
	if (src != nullptr)
	{
		int x = 20;
		int y = 20;
		int width = 150;
		int height = 150;
		int add = 150;
		cvSetImageROI(src,cvRect(x,y,width,height));
		cvAddS(src,cvScalar(add),src);
		cvResetImageROI(src);
		cvNamedWindow("ROI_add",1);
		cvShowImage("ROI_add",src);
		cvWaitKey();
	}
	return 0;
}

widthStep 를 교묘 하 게 사용 하면 같은 효 과 를 낼 수 있 습 니 다. 이 를 위해 다른 그림 머리 를 만 들 었 습 니 다. width 와 height 의 값 은 interest 와 같 습 니 다.rect 의 width 와 height 의 값 입 니 다. interest 를 눌 러 야 합 니 다.rect 시작 점 은 이미지 시작 점 (왼쪽 상단 또는 왼쪽 하단) 을 설정 하고 다음 단 계 는 하위 이미지 의 widthStep 와 큰 interest 를 설정 합 니 다.img 이 같 습 니 다. 이렇게 하면 하위 이미지 에서 큰 그림 의 안쪽 부분 에서 다음 줄 의 시작 부분 에 적합 한 위치 로 점차적으로 들 어 갈 수 있 습 니 다. 마지막 으로 하위 이미지 의 imageData 지침 을 설정 하여 관심 부분 구역 의 시작 을 가리 키 며 다음 과 같 습 니 다.
ROI 를 설정 하고 리 셋 하 는 것 이 더 편리 해 보이 는데 왜 widthStep 를 사용 합 니까?이 유 는 처리 하 는 과정 에서 그림 을 설정 하고 유지 하려 는 여러 개의 하위 영역 이 활성 상태 에 있 지만 ROI 는 직렬 로 만 처리 할 수 있 고 계속 설정 하고 리 셋 해 야 하기 때 문 입 니 다.
마스크 와 모드, 코드 예제 에서 cvAddS () 함수 가 네 번 째 매개 변 수 를 기본 값 으로 비 울 수 있 도록 합 니 다: const CVArr * mask = NULL. 이것 은 8 비트 단일 채널 배열 입 니 다. 임의의 모양 의 0 픽 셀 과 마스크 구역 으로 작업 을 제한 할 수 있 습 니 다. ROI 가 마스크 나 모드 에 따라 변 하면,프로 세 스 는 ROI 와 마스크 의 교차 영역 으로 제 한 됩 니 다. 마스크 나 모드 는 그림 을 지정 한 함수 에서 만 사용 할 수 있 습 니 다.

좋은 웹페이지 즐겨찾기