本文區分”
問題引出“、”
概念抽象
“、”
算法實現“三個部分
由表及里具體講解OpenCV圖像處理中“投影技術”的使用
,並通過”答題卡識別“”
OCR字符分割”“
壓板識別
”“
輪廓展開分析”四個的例子具體講解算法使用。使得讀者能夠對
“投影技術”加速認識和理解,從而在解決具體問題的時候多一個有效方法。
內容將涉及如下:
1. “投影技術”的基本概念
2. “投影技術”的數學抽象
3. “投影技術”的算法實現
4. “投影技術”在“答題卡識別”場景下的使用
5. “投影技術”在“OCR 字符分割”場景下的使用
6. “投影技術”在“壓板識別”例子中的使用
7. “投影技術”在“樹葉輪廓分析”中的使用
8. 如何在解決實際問題的時候采用靈活的方法
一、問題引出“
我第一次集中遇到需要“投影”技術解決的問題,是在“答題卡”項目中。
在這樣采集到的圖像中,大量存在黑色的定位區塊:

如果進一步定位,可以得到這樣的結果:

如果做成連續圖像
在這波峰波谷中,存在着的“量化”結果,對應了答題卡中的定位關系。
二、概念抽象
在前面的分析里,我們已經基本建立起“投影”的概念。從離散的角度來說,也就是:
局部最大值:
局部最小值:
類似於求極值、求切線等的情況。
三、算法實現
//投影到x或Y軸上,上波形為vup,下波形為vdown,gap為誤差間隔
void projection2(Mat src,vector
<
int
>
& vup,vector
<
int
>
& vdown,
int direction
= DIRECTION_X,
int gap
=
10);
void projection2(Mat src, vector
<
int
>
& vup, vector
<
int
>
& vdown,
int direction,
int gap) {
Mat tmp
= src.clone();
vector
<
int
> vdate;
if (DIRECTION_X
== direction) {
for (
int i
=
0; i
< tmp.cols; i
++) {
Mat data
= tmp.col(i);
int itmp
= countNonZero(data);
vdate.push_back(itmp);
}
}
else {
for (
int i
=
0; i
< tmp.rows; i
++) {
Mat data
= tmp.row(i);
int itmp
= countNonZero(data);
vdate.push_back(itmp);
}
}
//整形,去除長度小於gap的零的洞
if (vdate.size()
<
= gap)
return;
for (
int i
=
0; i
< vdate.size()
- gap; i
++) {
if (vdate[i]
>
0
&& vdate[i
+ gap]
>
0) {
for (
int j
= i; j
< i
+ gap; j
++) {
vdate[j]
=
1;
}
i
= i
+ gap
-
1;
}
}
//記錄上下沿
for (
int i
=
1; i
< vdate.size(); i
++) {
if (vdate[i
-
1]
==
0
&& vdate[i]
>
0)
vup.push_back(i);
if (vdate[i
-
1]
>
0
&& vdate[i]
==
0)
vdown.push_back(i);
}
}
在具體使用過程中,注意相關控制變量的管理。
四、問題遷移
1
、OCR字符分割
在這樣的OCR識別中,首先可以通過投影的方法,實現字符的分割。
2、
壓板識別
在這樣的項目中,同樣可以通過投影的方法,獲得各個壓板的准確定位。
3、輪廓展開分析
在類似樹葉這樣的測量中,可以通過“極坐標轉換”,將樹葉的這樣的曲線轉換成可以分析的投影,從而得到比如“樹葉有多少個分叉”“有無缺陷”這樣的定量信息。