When a camera observes a picture of a rectangle, it often only gets a distorted picture:
Original:
The reality is that cameras often look at pictures from a point of view:
Use the OPENCV perspective transformation to correct the picture to the angle of the face, probably the process:
1, through the gray, fuzzy and two-value to get:
2, and then to find the image of the outsourcing rectangle contour, and find the corner to get:
3, through the trapezoidal four corner points and the four vertices of the outsourced rectangle to get the transformation matrix, projection transformation, and finally get:
If the picture is not visible, please come to http://blog.csdn.net/baixiaozhe/article/details/51762086
The code is as follows:
Picture projection transformation-(void) wrapimg{uiimage *imageinview = [uiimage imagenamed:@ "wrap"];
Mat wrapsrc;
The default to 4 channels so below scalar also have to be 4 channels, otherwise can not correctly implement color Uiimagetomat (Imageinview, WRAPSRC); NSLog (@ "wrapsrc cols%d rows%d channels%d type%d depth%d elemsize%zu", Wrapsrc.cols,wrapsrc.rows,wrapsrc.channels (),
Wrapsrc.type (), wrapsrc.depth (), wrapsrc.elemsize ());
Gray Mat Graymat;
Cvtcolor (WRAPSRC, Graymat,color_bgr2gray);
Blur (Graymat, Graymat, Size2d (7,7));
Binary, gray scale greater than 14 of white need to adjust until appear white big trapezoid graymat=graymat>14;
Shi-tomasi angle Point algorithm parameter int maxcorners=4;
Vector<point2f> Corners;
Double qualitylevel=0.01;
The blocksize=7;//contour of the minimum distance between double mindistance=100;//corner points is more obvious, the greater the value is the bool Useharrisdetector=false;
Double k=0.04; Shi-tomasi Corner Detection Goodfeaturestotrack (Graymat,corners,maxcorners,qualitylevel,mindistance,mat (), BlockSize,
USEHARRISDETECTOR,K);
cout<< "Corner points detected:" <<corners.size () <<endl; NSLog (@ "Detected corner points:%lu", Corners.size ());
int r=10;
RNG RNG; Draw it out and see if it's four vertices. The point order detected by another corner point is not necessarily the same every time//if (Corners.size () ==4) {Circle (255,0, 0,255), 2,8,0);//Red Circle (Wrapsrc,corners[1],r,scalar (0,255,0,255), 2,8,0);//Green Circle (wrapsrc,corners[2],r,s Calar (0,0,255,255), 2,8,0);//Blue Circle (Wrapsrc,corners[3],r,scalar (255,255,0,255), 2,8,0);//yellow} _imageview.
Image= mattouiimage (WRAPSRC);
Return
* * STD::VECTOR<STD::VECTOR<CV::P oint>> contoursoutline;
Findcontours (graymat,contoursoutline,cv_retr_list,cv_chain_approx_simple);
Calculating the convex////bounding box Cv::rect boudrect for the contour;
Vector<point2i> Poly; for (int i = 0; i < contoursoutline.size ();
i++) {//bounding box boudrect= Boundingrect (Contoursoutline[i]);
Area filter int Tmparea=boudrect.area (); if (tmparea>= 50000) {Rectangle (Wrapsrc,cvpoint (BOUDRECT.X,BOUDRECT.Y), Cvpoint (Boudrect.br (). x, boudrect.br (). Y), Scalar (128), 2); }//src=wrapsrc (Boudrect); In this way screenshots sometimes go wrong somehow//with iOS Quartz API to capture UIImage *image=[uiimage Imagewithcgimage:cgimagecreatewithimageinrect ([
Imageinview Cgimage], CGRectMake (boudrect.x,boudrect.y,boudrect.width,boudrect.height))];
Mat SRC,WARP_DST;
Uiimagetomat (image, SRC);
WARP_DST = Mat::zeros (Src.rows, Src.cols, Src.type ());
From Trapezoidal Srctri[4] to the outsourced rectangular dsttri[4] point2f srctri[4];
POINT2F Dsttri[4];
POINT2F arect1=boudrect.tl ();
Trapezoidal four vertex order is upper left right upper left lower right lower point2f srcTri0 = point2f (corners[0].x-arect1.x, CORNERS[0].Y-ARECT1.Y);
point2f SrcTri1 = point2f (corners[2].x-arect1.x, CORNERS[2].Y-ARECT1.Y);
point2f srcTri2 = point2f (corners[1].x-arect1.x, CORNERS[1].Y-ARECT1.Y);
point2f SrcTri3 = point2f (corners[3].x-arect1.x, CORNERS[3].Y-ARECT1.Y); Find the midpoint of the outsourced rectangle from the top left, and then compare the four vertices of the trapezoid with the midpoint, such as X,y is lower than the midpoint, X is greater than the midpoint, and y is less than the midpoint to the upper right point2f BoudrectcenTER=POINT2F (SRC.COLS/2,SRC.ROWS/2);
if (srctri0.x>boudrectcenter.x) {if (SRCTRI0.Y>BOUDRECTCENTER.Y) {//lower right srctri[3]=srctri0;
}else{//right Upper Srctri[1]=srctri0;
}}else{if (SRCTRI0.Y>BOUDRECTCENTER.Y) {//lower left srctri[2]=srctri0;
}else{//left Upper Srctri[0]=srctri0; } if (srctri1.x>boudrectcenter.x) {if (SRCTRI1.Y>BOUDRECTCENTER.Y) {//lower right Srctri[3]=srctri
1;
}else{//right Upper Srctri[1]=srctri1;
}}else{if (SRCTRI1.Y>BOUDRECTCENTER.Y) {//lower left srctri[2]=srctri1;
}else{//left Upper Srctri[0]=srctri1; } if (srctri2.x>boudrectcenter.x) {if (SRCTRI2.Y>BOUDRECTCENTER.Y) {//lower right srctri[3]=srctr
I2;
}else{//right Upper Srctri[1]=srctri2;
}}else{if (SRCTRI2.Y>BOUDRECTCENTER.Y) {//lower left srctri[2]=srctri2; }else{//left Upper SRCTRi[0]=srctri2; } if (srctri3.x>boudrectcenter.x) {if (SRCTRI3.Y>BOUDRECTCENTER.Y) {//lower right srctri[3]=srctr
i3;
}else{//right Upper Srctri[1]=srctri3;
}}else{if (SRCTRI3.Y>BOUDRECTCENTER.Y) {//lower left srctri[2]=srctri3;
}else{//left Upper Srctri[0]=srctri3; }//Draw out to see if the order is Right circle (src,srctri[0],r,scalar (255,0,0,255), -1,8,0);//Red Left upper circle (src,srctri[1],r,scal AR (0,255,0,255), -1,8,0);//Green Right Upper Circle (Src,srctri[2],r,scalar (0,0,255,255), -1,8,0);//Blue Left lower circle (src,srctri[3],r,sc
Alar (255,255,0,255), -1,8,0);//Yellow right lower _imageview.image= mattouiimage (SRC);
Return
Four vertices of the outsourced rectangle, in order left upper right upper left lower right dsttri[0] = point2f (0,0);
DSTTRI[1] = point2f (src.cols-1, 0);
DSTTRI[2] = point2f (0, src.rows-1);
DSTTRI[3] = point2f (src.cols-1, src.rows-1);
Free Transform Perspective transformation Matrix 3*3 Mat Warp_matrix (3, 3, CV_32FC1); Warp_matrix=getpersPectivetransform (Srctri, Dsttri);
Warpperspective (SRC, warp_dst, Warp_matrix, Warp_dst.size (), warp_fill_outliers);
_imageview.image= mattouiimage (WARP_DST);
}
_imageview is the plug of the picture control