• 图像切边


     这里采用第一种方法

    待处理得图

      1 #include <opencv2/opencv.hpp>
      2 #include <iostream>
      3 #include <math.h>
      4 
      5 using namespace cv;
      6 using namespace std;
      7 
      8 Mat src, gray_src, dst;
      9 int threshold_value = 100;
     10 int max_level = 255;
     11 
     12 const char* output_win = "Contours Result";
     13 const char* roi_win = "Final Result";
     14 
     15 void FindROI(int, void*);
     16 void Check_Skew(int, void*);
     17 
     18 int main(int argc, char** argv) {
     19     src = imread("timg.jpg");
     20     if (src.empty()) {
     21         printf("could not load image...
    ");
     22         return -1;
     23     }
     24     namedWindow("input image", CV_WINDOW_AUTOSIZE);
     25     imshow("input image", src);
     26     namedWindow(output_win, CV_WINDOW_AUTOSIZE);
     27     Check_Skew(0, 0);
     28     // namedWindow(roi_win, CV_WINDOW_AUTOSIZE);
     29     //createTrackbar("Threshold:", output_win, &threshold_value, max_level, FindROI);
     30     // FindROI(0, 0);
     31 
     32     waitKey(0);
     33     return 0;
     34 }
     35 
     36 //将原图放正,如需切边还需执行另一个函数一次(因为不能对斜着的图直接切边)
     37 void Check_Skew(int, void*) {
     38     Mat canny_output;
     39     cvtColor(src, gray_src, COLOR_BGR2GRAY);
     40     Canny(gray_src, canny_output, threshold_value, threshold_value * 2, 3, false);
     41 
     42     vector<vector<Point>> contours;
     43     vector<Vec4i> hireachy;
     44     findContours(canny_output, contours, hireachy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));
     45     Mat drawImg = Mat::zeros(src.size(), CV_8UC3);
     46     float maxw = 0;
     47     float maxh = 0;
     48     double degree = 0;
     49 
     50     //获取最大旋转矩形的尺寸
     51     for (size_t t = 0; t < contours.size(); t++) {
     52         RotatedRect minRect = minAreaRect(contours[t]);
     53         degree = abs(minRect.angle);
     54         if (degree > 0) {//判断是否有旋转
     55             maxw = max(maxw, minRect.size.width);
     56             maxh = max(maxh, minRect.size.height);
     57         }
     58     }
     59     RNG rng(12345);
     60 
     61     //根据最大旋转矩形的尺寸,判断并画出来轮廓同时得到旋转角度
     62     for (size_t t = 0; t < contours.size(); t++) {
     63         RotatedRect minRect = minAreaRect(contours[t]);
     64         if (maxw == minRect.size.width && maxh == minRect.size.height) {//判断是否是最大边界
     65             degree = minRect.angle+90;//判断得是0点到height边的角度,逆时针为负,即使正放也有-90°所以要+90
     66             Point2f pts[4];
     67             minRect.points(pts);
     68             Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
     69             for (int i = 0; i < 4; i++) {
     70                 line(drawImg, pts[i], pts[(i + 1) % 4], color, 2, 8, 0);
     71             }
     72         }
     73     }
     74     printf("max contours width : %f
    ", maxw);
     75     printf("max contours height : %f
    ", maxh);
     76     printf("max contours angle : %f
    ", degree);
     77     imshow(output_win, drawImg);
     78 
     79     //旋转成正的
     80     Point2f center(src.cols / 2, src.rows / 2);//旋转中心
     81     Mat rotm = getRotationMatrix2D(center, degree, 1.0);//函数调用形式:
     82                                                         //Mat getRotationMatrix2D(Point2f center,表示旋转的中心点
     83                                                                                 //double angle, 表示旋转的角度
     84                                                                                 //double scale)        图像缩放因子                                        
     85     Mat dst;
     86     warpAffine(src, dst, rotm, src.size(), INTER_LINEAR, 0, Scalar(255, 255, 255));//仿射变换
     87     imshow("Correct Image", dst);
     88 }
     89 
     90 //无旋转的处理函数,对已经放正的函数切边
     91 void FindROI(int, void*) {
     92 
     93     //提取边缘
     94     cvtColor(src, gray_src, COLOR_BGR2GRAY);
     95     Mat canny_output;
     96     Canny(gray_src, canny_output, threshold_value, threshold_value * 2, 3, false);
     97 
     98     //绘制轮廓
     99     vector<vector<Point>> contours;
    100     vector<Vec4i> hireachy;
    101     findContours(canny_output, contours, hireachy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));
    102 
    103     //画出最大轮廓的最小外接矩形
    104     int minw = src.cols*0.75;
    105     int minh = src.rows*0.75;
    106     RNG rng(12345);
    107     Mat drawImage = Mat::zeros(src.size(), CV_8UC3);
    108     Rect bbox;
    109     for (size_t t = 0; t < contours.size(); t++) {
    110         RotatedRect minRect = minAreaRect(contours[t]);//获取轮廓t的最小外接矩形,RotatedRect旋转矩形,可以设置矩形中心,矩形长宽,旋转角度
    111         float degree = abs(minRect.angle);//获取旋转角度
    112         if (minRect.size.width > minw && minRect.size.height > minh && minRect.size.width < (src.cols - 5)) {//轮廓筛选,选出最大的外接矩形
    113             printf("current angle : %f
    ", degree);
    114             Point2f pts[4];
    115             minRect.points(pts);//将最大的外接矩形的四个点赋给pts
    116             bbox = minRect.boundingRect();//外接正矩形边界
    117             Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
    118             for (int i = 0; i < 4; i++) {
    119                 line(drawImage, pts[i], pts[(i + 1) % 4], color, 2, 8, 0);
    120             }
    121         }
    122     }
    123     imshow(output_win, drawImage);
    124 
    125     //用找到的最小外接矩形截取图像
    126     if (bbox.width > 0 && bbox.height > 0) {
    127         Mat roiImg = src(bbox);//用括号内的范围截取ROI区域
    128         imshow(roi_win, roiImg);
    129     }
    130     return;
    131 }
  • 相关阅读:
    自动封箱和拆箱
    关于Java的一道内存的题目
    volatile关键字
    阶乘尾零
    Java之final的解析
    从1到n整数中1出现的次数
    最小安装雷达数量
    二叉树重建
    最短路径—Dijkstra算法
    PAT A1063——set的常见用法详解
  • 原文地址:https://www.cnblogs.com/long5683/p/9741380.html
Copyright © 2020-2023  润新知