【OpenCV】透视变换-将图像由不规则四边形转换成矩形
来源:互联网 发布:泉州招聘 福建网络 编辑:程序博客网 时间:2024/06/06 13:09
本文是在点击打开链接基础上修改而成的,感谢原文博主提供的参考。
代码声明:近期在做身份证图像处理,由于采集问题,采集到的图像存在一定的角度偏差,成为了不规则的四边形,通过透视变换可将其转换成矩形,可以更好的进行分割。本文只提供相关函数和相关类。由于博主也是OpenCV新手,函数可能不那么完美,欢迎大家一起讨论。
class CPerspective{ private: vector<Vec4i> lines; double deltaRho; double deltaTheta; int minVote; double minLength; double maxGap; public: CPerspective() : deltaRho(1), deltaTheta(CV_PI/180), minVote(10), minLength(0.), maxGap(0.) {} void setAccResolution(double dRho, double dTheta) { deltaRho= dRho; deltaTheta= dTheta; } void setMinVote(int minv) { minVote= minv; } void setLineLengthAndGap(double length, double gap) { minLength= length; maxGap= gap; } std::vector<Vec4i> findLines(Mat& binary) { lines.clear(); HoughLinesP(binary,lines, deltaRho, deltaTheta, minVote, minLength, maxGap); return lines; } vector<Vec4i> drawVerticalLines(Mat &image, Scalar color=Scalar(0,0,255)){ vector<Vec4i>::const_iterator iter=lines.begin(); vector<Vec4i> verline;while (iter!=lines.end()) { Point pt1((*iter)[0],(*iter)[1]); Point pt2((*iter)[2],(*iter)[3]); if(pt1.x == pt2.x || (pt2.y-pt1.y)/(pt2.x-pt1.x)>1 || (pt2.y-pt1.y)/(pt2.x-pt1.x)<-1) {//line(image, pt1, pt2, color); verline.push_back(*iter);++iter; }else++iter;} return verline; } vector<Vec4i> drawHorizontalLines(Mat &image, Scalar color=Scalar(0,0,255)){ vector<Vec4i>::const_iterator iter1 = lines.begin();vector<Vec4i>::const_iterator iter2 = lines.begin();vector<Vec4i>::const_iterator top_iter = iter1;vector<Vec4i>::const_iterator bottom_iter = iter1;vector<Vec4i> horline;int miny = (*iter1)[1], maxy = (*iter1)[1];while (iter1!=lines.end()) {if(miny > (*iter1)[1]){miny = (*iter1)[1]; top_iter = iter1;iter1++; }elseiter1++;}Point pt_top1((*top_iter)[0],(*top_iter)[1]); Point pt_top2((*top_iter)[2],(*top_iter)[3]); //line(image, pt_top1, pt_top2, color); horline.push_back(*top_iter);while (iter2!=lines.end()) {if(maxy < (*iter2)[1]){maxy = (*iter2)[1]; bottom_iter = iter2;iter2++; }elseiter2++;}Point pt_bottom1((*bottom_iter)[0],(*bottom_iter)[1]); Point pt_bottom2((*bottom_iter)[2],(*bottom_iter)[3]); //line(image, pt_bottom1, pt_bottom2, color); horline.push_back(*bottom_iter);return horline; } static CvPoint computeIntersect(Vec4i a, Vec4i b){int x1 = a[0], y1 = a[1], x2 = a[2], y2 = a[3];int x3 = b[0], y3 = b[1], x4 = b[2], y4 = b[3];if (float d = ((float)(x1-x2) * (y3-y4)) - ((y1-y2) * (x3-x4))){CvPoint pt;pt.x = ((x1*y2 - y1*x2) * (x3-x4) - (x1-x2) * (x3*y4 - y3*x4)) / d;pt.y = ((x1*y2 - y1*x2) * (y3-y4) - (y1-y2) * (x3*y4 - y3*x4)) / d;return pt;}}};
IplImage* mycvPerspectiveCorrectionImage(Mat& image){ Mat cannyMat; Canny (image, cannyMat, 60, 220, 3); CPerspective findVertex; findVertex.setMinVote (90); findVertex.setLineLengthAndGap (100,80); findVertex.findLines (cannyMat); vector<Vec4i> horline = findVertex.drawVerticalLines (image); vector<Vec4i> verline = findVertex.drawHorizontalLines(image);CvPoint2D32f srcVertex[4], dstVertex[4];srcVertex[0].x = CPerspective::computeIntersect(horline[1], verline[0]).x; srcVertex[0].y = CPerspective::computeIntersect(horline[1], verline[0]).y; srcVertex[1].x = CPerspective::computeIntersect(horline[0], verline[0]).x; srcVertex[1].y = CPerspective::computeIntersect(horline[0], verline[0]).y; srcVertex[2].x = CPerspective::computeIntersect(horline[1], verline[1]).x; srcVertex[2].y = CPerspective::computeIntersect(horline[1], verline[1]).y; srcVertex[3].x = CPerspective::computeIntersect(horline[0], verline[1]).x; srcVertex[3].y = CPerspective::computeIntersect(horline[0], verline[1]).y; dstVertex[0].x = 0;dstVertex[0].y = 0;dstVertex[1].x = image.cols-1;dstVertex[1].y = 0;dstVertex[2].x = 0;dstVertex[2].y = image.rows-1;dstVertex[3].x = image.cols-1;dstVertex[3].y = image.rows-1;CvMat* warp_mat = cvCreateMat( 3, 3, CV_32FC1 ); cvGetPerspectiveTransform( srcVertex, dstVertex, warp_mat ); IplImage* srcImg = &IplImage(image);IplImage* dstImg = cvCloneImage(srcImg);cvWarpPerspective(srcImg, dstImg, warp_mat, CV_INTER_LINEAR, cvScalarAll(255)); //cvNamedWindow( "Perspective Warp" ); //cvShowImage( "Perspective Warp", dstImg ); //最终是输出dst return dstImg;}
运行结果:原图像--目标图像
0 0
- 【OpenCV】透视变换-将图像由不规则四边形转换成矩形
- OpenCV 透视变换【图像归一化矫正】
- opencv 拉伸、扭曲、旋转图像-透视变换
- OpenCV图像变换(仿射变换与透视变换)
- 图像的仿射变换与透视变换opencv
- 【opencv】opencv图像透视变换和二值化处理
- 【opencv】鱼眼图像畸变校正——透视变换
- opencv 图像畸变矫正加速、透视变换加速方法总结
- 基于OpenCV的图像配准之后的透视变换
- 【OpenCV】之find_obj基础上的局部图像透视变换
- opencv 图像畸变矫正加速、透视变换加速方法总结
- 图像的透视变换
- 图像校正-透视变换
- opencv 透视变换
- OpenCV透视变换
- opencv 透视变换
- OpenCV 透视变换实例
- opencv之透视变换
- 关于蛇形填数问题求解
- Nginxs学习-1安装Nginx 将Nginx作为静态网页服务器
- python中调用matlab函数
- Android输入法弹出,布局上移,背景不会压缩
- Windows 10驱动签名_win 10驱动数字签名_驱动签名注意事项
- 【OpenCV】透视变换-将图像由不规则四边形转换成矩形
- 复习了一下NGUI
- iOS每日一记——————————三方库。。。。
- google地图项目总结
- 判断移动端打开的是ios还是android还是微信浏览器
- Data Vault初探(九) —— 定期装载_Kettle_附属表
- Java数据库连接 - 预编译SQL语句
- Android 程序运行崩溃:Resource is not a drawable (color or path)
- iOS 如何跳到设置app