opencv如何求输入图像的子图像(三种方案)

本文系原创,转载请注明出处。

我这里介绍三两种方法。第一种新建一个图像;第二种也是新建图像,直接操作数据体,效率会高些;第三种方法直接创建头,用源图像的数据体,用这种方法记得释放新建的头不是释放整个图像。

相比之下,第三种方法不用创建数据体,效率会高很多。第二种方法其次,第一种效率最低。

 

第一种:

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; yheight; 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;
}


你可能感兴趣的:(OpenCV,Learning)