1、問題:
如圖,如何對圖片中的一串數字進行有順序、從左到右的分割?
(圖片來源https://blog.csdn.net/LTG01/article/details/50492556)
2、思路
- 將圖片轉換成灰度圖。
- 將灰度圖像轉換成黑底白字的二值圖像。
- 通過列掃描,確認本列中是否存在白色像素,如果存在,記下此時的列數。
- 通過行掃描,確認本行中是否存在白色像素,如果存在,記下此時的行數。
- 將保存下來的行數以及列數進行有重組,得到圖像中一個數字的有效矩形邊界,並將矩形座標保存下來。
- 使用rectangle()函數,將全部矩形都繪製在彩色圖形中。
- 使用所有矩形得到源圖像中的所有數字單獨的感興趣區域,這樣就實現了將所有數字全部分離出來的目的。
3、相關函數
- 轉換成灰度圖:cvtColor()。
- 轉換成二值圖像:threshold()。這裏不建議使用Canny()。
- 使用動態地址獲得圖像的像素值。具體代碼參考:https://blog.csdn.net/qq_38316300/article/details/100109246
- 繪製矩形:rectangle()。
- 獲得感興趣區域。
4、部分代碼講解
1.將圖像轉換成灰度圖像:
Mat grayImage;
cvtColor(srcImage, grayImage, COLOR_BGR2GRAY);
2.將圖形二值化,轉換成黑底白字的圖像:
Mat binaryImage;
threshold(~grayImage, binaryImage, 100, 255, THRESH_BINARY);
3.使用動態地址獲得圖像中的所有像素點:
for (size_t col = 0; col < colsImg; col++) {
// 獲得行像素
for (size_t row = 0; row < rowsImg; row++) {
pixel = binaryPic.at<uchar>(row, col);
}
4.先進行列掃描,確定所有矩形x的座標;再進行列掃描,去頂所有矩形的y座標。其中,這點需要注意,如果我們不加以篩選,我們將會獲得覆蓋一個數字的所有像素座標。比如,1這個數字佔了十行三列,如果我們不加以篩選,這一個數字我們就會獲得3個x座標以及10個y座標,這顯然不是我們所需要的。我們需要的座標只是數字1最外圍的最小矩形的四個座標。
5.將得到的所有矩形進行繪製:
rectangle(dstImage, Rect(rectPoint[i].x, rectPoint[ i].y, rectPoint[i+2].x - rectPoint[i].x, rectPoint[1].y - rectPoint[0].y),
Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), 1);
6.得到十個數字的是個感興趣區域,完成分割:
Mat roiImage = dstImage(Rect(rectPoint[i].x, rectPoint[i].y, rectPoint[i + 2].x -
rectPoint[i].x,rectPoint[1].y - rectPoint[0].y));
5、完成代碼
完成代碼詳見:https://download.csdn.net/download/qq_38316300/11654183