使用OpenCV对图像进行切边

一、概述

  案例:使用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:对正常图片切边”的步骤来实现图片的切边  

二、代码示例

/*将旋转图片转成正常图片*/
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); }

 

 

三、图片示例

 

posted on 2022-03-16 10:41  飘杨......  阅读(426)  评论(0编辑  收藏  举报