Bartosz Bialecki
Bartosz Bialecki

Reputation: 4451

Crop image with OpenCV

I have a problem with cropping image using OpenCV library on iPhone. I have an image with selected area and I'd like to crop image with this area. But the new image isn't map to rectangle and the new image has also blue color of text.

I use that code to crop image:

    IplImage *src = [OpenCV CreateIplImageFromUIImage:image];


NSValue *val = [corners objectAtIndex:0];
CGPoint p1 = [val CGPointValue];
val = [corners objectAtIndex:1];
CGPoint p2 = [val CGPointValue];
val = [corners objectAtIndex:2];
CGPoint p3 = [val CGPointValue];
val = [corners objectAtIndex:3];
CGPoint p4 = [val CGPointValue];

float minX = fmin(fmin(p1.x, p2.x), fmin(p3.x, p4.x));
float minY = fmin(fmin(p1.y, p2.y), fmin(p3.y, p4.y));
float maxX = fmax(fmax(p1.x, p2.x), fmax(p3.x, p4.x));
float maxY = fmax(fmax(p1.y, p2.y), fmax(p3.y, p4.y));

CGFloat width = maxX - minX;
CGFloat height = maxY - minY;

IplImage *dst = cvCreateImage(cvSize(width, height), 8, 3);

p1 = CGPointMake(p1.x - minX, p1.y - minY);
p2 = CGPointMake(p2.x - minX, p2.y - minY);
p3 = CGPointMake(p3.x - minX, p3.y - minY);
p4 = CGPointMake(p4.x - minX, p4.y - minY);

IplImage* cropped = cvCreateImage(cvSize(width, height), src->depth, src->nChannels);

cvSetImageROI(src, cvRect(minX, minY, width, height));

cvCopy(src, cropped, NULL);
cvResetImageROI(src);
cvReleaseImage(&src);

CvMat* mmat = cvCreateMat(3, 3, CV_32FC1);

CvPoint2D32f *c1 = (CvPoint2D32f *)malloc(4 * sizeof(CvPoint2D32f));
CvPoint2D32f *c2 = (CvPoint2D32f *)malloc(4 * sizeof(CvPoint2D32f));

c1[0].x = p1.x;   c1[0].y = p1.y;
c1[1].x = p4.x;   c1[1].y = p4.y;
c1[2].x = p2.x;   c1[2].y = p2.y;
c1[3].x = p3.y;   c1[3].y = p3.y;

c2[0].x = 0;   c2[0].y = 0;
c2[1].x = width;   c2[1].y = 0;
c2[2].x = 0;   c2[2].y = height;
c2[3].x = width;   c2[3].y = height;

    mmat = cvGetPerspectiveTransform(c1, c2, mmat);
cvWarpPerspective(cropped, dst, mmat, CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS, cvScalarAll(0));

I will be grateful for any help.

Upvotes: 1

Views: 3070

Answers (1)

Bartosz Bialecki
Bartosz Bialecki

Reputation: 4451

I had an error in my code. If someone is interested here is working code:

IplImage *src = [OpenCV CreateIplImageFromUIImage:image];

IplImage *dst = cvCloneImage(src);
dst->origin = src->origin;
dst->nChannels = src->nChannels;
dst->depth = src->depth;

cvZero(dst);

NSValue *val = [corners objectAtIndex:0];
CGPoint p1 = [val CGPointValue];
val = [corners objectAtIndex:1];
CGPoint p2 = [val CGPointValue];
val = [corners objectAtIndex:2];
CGPoint p3 = [val CGPointValue];
val = [corners objectAtIndex:3];
CGPoint p4 = [val CGPointValue];

CGFloat width = src->width;
CGFloat height = src->height;

CvMat* mmat = cvCreateMat(3, 3, CV_32FC1);

CvPoint2D32f *c1 = (CvPoint2D32f *)malloc(4 * sizeof(CvPoint2D32f));
CvPoint2D32f *c2 = (CvPoint2D32f *)malloc(4 * sizeof(CvPoint2D32f));

c1[0].x = round(p1.x);   c1[0].y = round(p1.y);
c1[1].x = round(p4.x);   c1[1].y = round(p4.y);
c1[2].x = round(p2.x);   c1[2].y = round(p2.y);
c1[3].x = round(p3.x);   c1[3].y = round(p3.y);

c2[0].x = 0;            c2[0].y = 0;
c2[1].x = width -1;     c2[1].y = 0;
c2[2].x = 0;            c2[2].y = height - 1;
c2[3].x = width - 1;    c2[3].y = height - 1;

mmat = cvGetPerspectiveTransform(c1, c2, mmat);
free(c1);
free(c2);

cvWarpPerspective(src, dst, mmat, CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS, cvScalarAll(0));

cvReleaseImage(&src);
cvReleaseMat(&mmat);

UIImage *newImage = [OpenCV UIImageFromIplImage:dst];
cvReleaseImage(&dst);

Upvotes: 2

Related Questions