本文系原创,转载请注明出处。
我这里介绍三两种方法。第一种新建一个图像;第二种也是新建图像,直接操作数据体,效率会高些;第三种方法直接创建头,用源图像的数据体,用这种方法记得释放新建的头不是释放整个图像。
相比之下,第三种方法不用创建数据体,效率会高很多。第二种方法其次,第一种效率最低。
第一种:
IplImage* cvextGetSubImgCpOr(IplImage *srcImg, CvRect rect)
{
if(!srcImg) return NULL;
IplImage *subImg = NULL;
cvSetImageROI(srcImg, rect);
subImg = cvCreateImage( cvSize(rect.width, rect.height), srcImg->depth, srcImg->nChannels );
cvCopy(srcImg, subImg);
cvResetImageROI(srcImg);
return subImg;
}
第二种:
IplImage* cvextGetSubImgCp(const IplImage *srcImg, CvRect rect)
{
if(!srcImg) return NULL;
IplImage *subImg = cvCreateImage(cvSize(rect.width, rect.height),srcImg->depth, srcImg->nChannels);
if(!subImg) return NULL;
for(int y=0; y<subImg->height; y++)
{
memcpy(subImg->imageData + y * subImg->widthStep,
(srcImg->imageData + rect.y * srcImg->widthStep + rect.x * srcImg->nChannels)
+ y * srcImg->widthStep, subImg->width * subImg->nChannels * subImg->depth/8);
}
return subImg;
}
第三种:
IplImage* cvextGetSubImgNonCp(const IplImage *srcImg, CvRect rect)
{
if(!srcImg) return NULL;
IplImage *subImg = NULL;
subImg = cvCreateImageHeader(cvSize(rect.width, rect.height), srcImg->depth, srcImg->nChannels);
if(!subImg) return NULL;
subImg->origin = srcImg->origin;
subImg->widthStep = srcImg->widthStep;
subImg->imageData = srcImg->imageData + rect.y * srcImg->widthStep + rect.x * srcImg->nChannels;
return subImg;
}