截取图中上方数码管中的数字
基本思路:
1、将图像转化为灰度图
2、截取ROI区域
3、二值化
4、循环遍历每一行和每一列,得到字符的坐标
5、截取并保存
1 #include <opencv2/opencv.hpp> 2 #include <iostream> 3 #include <math.h> 4 #include <stdio.h> 5 6 using namespace cv; 7 using namespace std; 8 9 10 int getColSum(Mat& src, int t); 11 int getRowSum(Mat& src, int t); 12 void cutLeft(Mat& src, Mat& leftImg, Mat& rightImg); 13 void cutTop(Mat& src, Mat& dstImg); 14 15 int main() 16 { 17 Mat src = imread("数字.jpg", 0); 18 threshold(src, src, 0, 255, THRESH_BINARY|THRESH_OTSU); 19 imshow("origin", src); 20 21 22 23 Mat roi = src(Rect(250, 25, src.cols-350, 300));//截取ROI区域 24 imshow("ROI", roi); 25 //形态学操作去除干扰 26 Mat kernel = getStructuringElement(MORPH_RECT, Size(7, 7), Point(-1, -1)); 27 morphologyEx(roi, roi, MORPH_OPEN, kernel); 28 29 Mat kernel2 = getStructuringElement(MORPH_RECT, Size(7,7), Point(-1, -1)); 30 dilate(roi, roi, kernel2); 31 imshow("ROI", roi); 32 33 Mat leftImg, rightImg; 34 35 rightImg = roi.clone(); 36 string nameLeft[5] = {"digital_1.jpg","digital_2.jpg" ,"digital_3.jpg" ,"digital_4.jpg" ,"digital_5.jpg" }; 37 for (int i = 0; i < 5; i++) { 38 39 cutLeft(rightImg, leftImg, rightImg); 40 imwrite(nameLeft[i], leftImg);//保存 41 } 42 43 44 45 waitKey(0); 46 return 0; 47 } 48 //函数作用:计算某一列的像素和 49 //输入为二值图像 50 int getColSum(Mat& src, int t) { 51 int rowNumber = src.rows;//行数 52 int colNumber = src.cols;//列数 53 uchar ColSum = 0; 54 for (int i = 0; i < rowNumber; i++) 55 { 56 for (int j = 0; j < colNumber; j++) 57 { 58 if (j == t) 59 { 60 61 ColSum += src.at<uchar>(i, j); 62 } 63 64 } 65 } 66 return ColSum; 67 } 68 69 int getRowSum(Mat& src, int t) { 70 int rowNumber = src.rows;//行数 71 int colNumber = src.cols;//列数 72 uchar RowSum = 0; 73 for (int i = 0; i < rowNumber; i++) 74 { 75 if (i== t) 76 { 77 78 for (int j = 0; j < colNumber; j++) 79 { 80 81 RowSum += src.at<uchar>(i, j); 82 83 84 } 85 } 86 } 87 return RowSum; 88 } 89 void cutLeft(Mat& src, Mat& leftImg, Mat& rightImg)//左右切割 90 { 91 int left, right; 92 left = 0; 93 right = src.cols; 94 95 //循环遍历每一列,记录下左端的坐标 96 int i; 97 for (i = 0; i < src.cols; i++) 98 { 99 int colValue = getColSum(src, i); 100 //cout <<i<<" th "<< colValue << endl; 101 if (colValue > 0) 102 { 103 left = i; 104 break; 105 } 106 } 107 108 //接着循环遍历每一列,记录下右端的坐标 109 for (; i < src.cols; i++) 110 { 111 int colValue = getColSum(src, i); 112 //cout << i << " th " << colValue << endl; 113 if (colValue == 0) 114 { 115 right = i; 116 break; 117 } 118 } 119 120 121 int width = right - left;//计算字符的宽度 122 123 Rect rect(left, 0, width, src.rows); 124 leftImg = src(rect); 125 Rect rectRight(right, 0, src.cols - right, src.rows); 126 rightImg = src(rectRight); 127 cutTop(leftImg, leftImg); 128 129 } 130 131 void cutTop(Mat& src, Mat& dstImg)//上下切割 132 { 133 int top, bottom; 134 top = 0; 135 bottom = src.rows; 136 137 int i; 138 for (i = 0; i < src.rows; i++) 139 { 140 int colValue = getRowSum(src, i); 141 //cout <<i<<" th "<< colValue << endl; 142 if (colValue > 0) 143 { 144 top = i; 145 break; 146 } 147 } 148 for (; i < src.rows; i++) 149 { 150 int colValue = getRowSum(src, i); 151 //cout << i << " th " << colValue << endl; 152 if (colValue == 0) 153 { 154 bottom = i; 155 break; 156 } 157 } 158 159 int height = bottom - top; 160 Rect rect(0, top, src.cols, height); 161 dstImg = src(rect); 162 }