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模块,面试题等等)↓↓↓↓↓↓见下面↓↓文章底部点击莬费领取↓↓