2010-09-24 192 views
1

我在使用iPhone上的OpenCV庫裁剪圖像時遇到了問題。我有一個與選定區域的圖像,我想裁剪該區域的圖像。但新圖像不是映射到矩形,新圖像也是藍色文本。用OpenCV裁剪圖像

我使用該代碼即可裁剪圖片:

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)); 

我會感謝任何幫助。

+0

爲什麼不嘗試在不使用扭曲的情況下看到裁剪後的圖像? – rics 2010-09-25 20:11:27

+0

選中的不能是矩形。它可以是任何四邊形,我想先將該圖像裁剪到該四邊形,然後將該四邊形映射到矩形。但有了上述功能,我只能將圖像裁剪到矩形區域,並且翹曲不起作用。 – 2010-09-27 07:41:50

+0

我們如何檢測角落?你能給我提供指導方針或一點點代碼嗎? – QueueOverFlow 2012-10-27 09:24:04

回答

2

我的代碼有錯誤。如果有人對此感興趣,請點擊這裏工作代碼:

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);