1、概述
案例:使用OpenCV对旋转图片及正常图片进行切边。
A:对正常图片切边的步骤
1.加载图像
2.对图像进行灰度化
3.边缘检测
4.轮廓发现
5.找出符合目标的最大外接矩形,并使用矩形的四个坐标点绘制线
6.根据找到Rect在原图上切除ROI区域
7.显示ROI区域
B:对旋转图像切边的步骤
1.加载原图
2.对图像进行灰度化
3.边缘检测
4.轮廓发现
5.找出图像旋转角度(a.找出旋转矩形的最大宽和最大高 b.找出这个目标矩形的旋转角度及旋转矩形。c.把此矩形绘制出来)
6.根据图片中心点及旋转角度,利用getRotationMatrix2D制作目标旋转Mat
7.利用wrapAffine+第6步的旋转矩阵实现最终的旋转
8.此时的图片为正确的旋转图片,可以利用“A:对正常图片切边”的步骤来实现图片的切边
2、代码示例
/*将旋转图片转成正常图片*/void CaseOneEdgeCutting::correctImageAngle(Mat & target){src = imread(filePath.toStdString().c_str());if(src.empty()){qDebug()<<"加载图片异常";return;}imshow("src",src);//降噪cvtColor(src,gray,COLOR_BGR2GRAY);imshow("gray",gray);//边缘检测Canny(gray,gray,threshold_value,threshold_value*2);imshow("canny",gray);//轮廓发现vector<vector<Point>> contours;vector<Vec4i> hierarchy;findContours(gray,contours,hierarchy,RETR_TREE,CHAIN_APPROX_SIMPLE);Mat resultImage = Mat::zeros(src.size(),CV_8UC3);float width = 0;float height = 0;RNG rng(12345);float degree = 0;for(size_t t =0;t<contours.size();t++){//找到角度RotatedRect minRect = minAreaRect(contours[t]);degree = abs(minRect.angle);if(degree>0){width = max(width,minRect.size.width);height = max(height,minRect.size.height);}}for(size_t t = 0;t<contours.size();t++){RotatedRect minRect = minAreaRect(contours[t]);if (width == minRect.size.width && height == minRect.size.height) {degree = minRect.angle;qDebug()<<"degree:"<<degree;Point2f pts[4];minRect.points(pts);Scalar color = Scalar(0,0,255);for(int i=0;i<4;i++){line(resultImage,pts[i], pts[(i + 1)%4], color, 2, 8, 0);}}}imshow("result1",resultImage);Point2f center(src.cols/2,src.rows/2);//图片中心点Mat degreeRoi = getRotationMatrix2D(center,-degree,1);warpAffine(src,target,degreeRoi,src.size(),INTER_LINEAR, 0, Scalar(255, 255, 255));imshow("dst",target);}
/*正常图片找到ROI区域*/
void CaseOneEdgeCutting::findEdgeCuttingROIImage(Mat &target){Mat srcTarget = target.clone();//降噪cvtColor(target,target,COLOR_BGR2GRAY);//边缘检测Canny(target,target,threshold_value,threshold_value*2);imshow("target",target);//轮廓发现vector<vector<Point>> contours;vector<Vec4i> hierarchy;findContours(target,contours,hierarchy,RETR_TREE,CHAIN_APPROX_SIMPLE);Mat resultImage = Mat::zeros(src.size(),CV_8UC3);float width = target.cols*0.5;float height = target.rows*0.5;RNG rng(12345);Rect box;for(size_t t = 0;t<contours.size();t++){RotatedRect minRect = minAreaRect(contours[t]);if(minRect.size.width>width&&minRect.size.height>height&&minRect.size.width<(src.cols-60)){qDebug()<<"执行到了这里";Point2f pts[4];minRect.points(pts);box = minRect.boundingRect();Scalar color = Scalar(rng.uniform(0,255),rng.uniform(0,255),rng.uniform(0,255));for(int i=0;i<4;i++){line(resultImage,pts[i], pts[(i + 1)%4], color, 2, 8, 0);}}}imshow("result2",resultImage);// //绘制roi区域Mat roiImage = srcTarget(box);imshow("roiImage",roiImage);
}
3、图片示例
本文福利,莬费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QSS,OpenCV,Quick模块,面试题等等)↓↓↓↓↓↓见下面↓↓文章底部点击莬费领取↓↓