自动透视校正为四边形对象
来源:互联网 发布:淘宝羽绒服 编辑:程序博客网 时间:2024/06/05 05:01
参考opencv开源上的,跑通了 注释了一下,以便后续学习
#include <opencv2/imgproc/imgproc.hpp>#include <opencv2/highgui/highgui.hpp>#include <iostream>
cv::Point2f center(0,0);cv::Point2f computeIntersect(cv::Vec4i a,cv::Vec4i b){int x1 = a[0],y1 = a[1],x2 = a[2],y2 = a[3],x3 = b[0],y3 = b[1],x4 = b[2],y4 = b[3];if (float d = ((float)(x1 - x2)*(y3 - y4)-(y1 - y2)*(x3 - x4))){cv::Point2f 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;}elsereturn cv::Point2f(-1,-1);}void sortCorners(std::vector<cv::Point2f>& corners,cv::Point2f center){std::vector<cv::Point2f> top,bot;for (unsigned int i =0;i< corners.size();i++){if (corners[i].y<center.y){top.push_back(corners[i]);}else{bot.push_back(corners[i]);}}cv::Point2f tl = top[0].x > top[1].x ? top[1] : top[0];cv::Point2f tr = top[0].x > top[1].x ? top[0] : top[1];cv::Point2f bl = bot[0].x > bot[1].x ? bot[1] : bot[0];cv::Point2f br = bot[0].x > bot[1].x ? bot[0] : bot[1];corners.clear();//注意以下存放顺序是顺时针,当时这里出错了,如果想任意顺序下文开辟的四边形矩阵注意对应corners.push_back(tl);corners.push_back(tr);corners.push_back(br);corners.push_back(bl);}
算法流程:先彩色转灰度,然后模糊求canny边缘,再用hough检测直线,求出四线交点,利用opencv自带的求透视矩阵的函数求出透视矩阵,然后利用透视矩阵转换源图像所需的四边形,效果图后续见图片:
int main(){cv::Mat src = cv::imread("C:/Users/Public/Pictures/Sample Pictures/perspective-quadrilateral-src-img.jpg");if (src.empty()){return -1;}cv::Mat bw;cv::cvtColor(src,bw,CV_BGR2GRAY);imshow("gray_src",bw);cv::blur(bw,bw,cv::Size(3,3));imshow("blur",bw);cv::Canny(bw,bw,100,100,3);imshow("cannyblur",bw);std::vector<cv::Vec4i> lines;cv::HoughLinesP(bw,lines,1,CV_PI/180,70,30,10);//1像素分辨能力 1度的角度分辨能力>70可以检测成连线30是最小线长//在直线L上的点(且点与点之间距离小于maxLineGap=10的)连成线段,然后这些点全部删除,并且记录该线段的参数,就是起始点和终止点//needed for visualization only//这里是将检测的线调整到延长至全屏,即射线的效果,其实可以不必这么做for (unsigned int i = 0;i<lines.size();i++){cv::Vec4i v = lines[i];lines[i][0] = 0;lines[i][1] = ((float)v[1] - v[3])/(v[0] - v[2])* -v[0] + v[1];lines[i][2] = src.cols;lines[i][3] = ((float)v[1] - v[3])/(v[0] - v[2])*(src.cols - v[2]) + v[3]; }std::vector<cv::Point2f> corners;//线的交点存储for (unsigned int i = 0;i<lines.size();i++){for (unsigned int j=i+1;j<lines.size();j++){cv::Point2f pt = computeIntersect(lines[i],lines[j]);if (pt.x >= 0 && pt.y >=0){corners.push_back(pt);}}}std::vector<cv::Point2f> approx;cv::approxPolyDP(cv::Mat(corners),approx,cv::arcLength(cv::Mat(corners),true)*0.02,true);if (approx.size()!=4){std::cout<<"The object is not quadrilateral(四边形)!"<<std::endl;return -1;}//get mass centerfor (unsigned int i = 0;i < corners.size();i++){center += corners[i];}center *=(1./corners.size());sortCorners(corners,center);cv::Mat dst = src.clone();//Draw Linesfor (unsigned int i = 0;i<lines.size();i++){cv::Vec4i v = lines[i];cv::line(dst,cv::Point(v[0],v[1]),cv::Point(v[2],v[3]),CV_RGB(0,255,0));//目标版块画绿线 }//draw corner pointscv::circle(dst,corners[0],3,CV_RGB(255,0,0),2);cv::circle(dst,corners[1],3,CV_RGB(0,255,0),2);cv::circle(dst,corners[2],3,CV_RGB(0,0,255),2);cv::circle(dst,corners[3],3,CV_RGB(255,255,255),2);//draw mass centercv::circle(dst,center,3,CV_RGB(255,255,0),2);cv::Mat quad = cv::Mat::zeros(300,220,CV_8UC3);//设定校正过的图片从320*240变为300*220//corners of the destination imagestd::vector<cv::Point2f> quad_pts;quad_pts.push_back(cv::Point2f(0,0));quad_pts.push_back(cv::Point2f(quad.cols,0));//(220,0)quad_pts.push_back(cv::Point2f(quad.cols,quad.rows));//(220,300)quad_pts.push_back(cv::Point2f(0,quad.rows));// Get transformation matrixcv::Mat transmtx = cv::getPerspectiveTransform(corners,quad_pts);//求源坐标系(已畸变的)与目标坐标系的转换矩阵// Apply perspective transformation透视转换cv::warpPerspective(src,quad,transmtx,quad.size());cv::imshow("src",src);cv::imshow("image",dst);cv::imshow("quadrilateral",quad);cv::waitKey();return 0;}
参考网址http://opencv-code.com/tutorials/automatic-perspective-correction-for-quadrilateral-objects/
- 自动透视校正为四边形对象
- 透视校正
- OpenCVForUnity 透视校正,透视变换
- 透视校正插值
- 透视校正插值
- 透视校正插值
- 图像校正-透视变换
- 透视纹理校正公式推导
- 图像校正—透视变换
- openGL 透视校正插值
- 透视变换畸变校正 双线性
- 计算当前四边形是否为凸四边形
- 图像预处理——透视变换(三):校正步骤
- 基于opencv的图像梯形畸变(透视)校正
- matlab练习程序(倾斜校正,透视变换)
- 【opencv】鱼眼图像畸变校正——透视变换
- 鱼眼图像畸变校正——透视变换
- matlab练习程序(倾斜校正,透视变换)
- java中的static
- 例解 autoconf 和 automake 生成 Makefile 文件
- 问题一百四十六:偶数求和
- JUnit4 中@AfterClass @BeforeClass @after @before的区别对比
- 海豚播放器 ffmpeg 编译之经历
- 自动透视校正为四边形对象
- LAN 语音聊天
- Linux下sysctl函数的使用
- 删除txt文件指定的行,按行读取txt文档数据
- hdu 1070 Milk
- opencv中cvMatchTemplate模板匹配
- 有待理解的CLR
- 使用UMDH 定位内存泄漏小结
- 第四届蓝桥杯本科A组解题报告(和B组相同的题目详见B组解题报告)