一、目標問題
對於已經成功切片的答題卡客觀題部分內容進行具體識別,得到答題結果。客觀題部分分為3類,分別是學號、單選題、多選題。
學號:

單選題:
多選題:
二、解題思路
目標的缺點在於無定位點,優點在於采集質量比較高、相對位置固定,故計划直接采用"划分ROI區域->識別灰度值"的方法進行識別。
學號的排列最為簡單,可以采用x_blank,x_step,y_blank,y_step的方式來輔助定位:
單選題的排序較為復雜
多選題雖然只有一行,復雜度和單選是一樣的。
三、算法研究
有用的算法需要采用逐步的方式實現。從最外部來看,每一個部分都是雙重(三重循環)
for (size_t i_index
=
0; i_index
<
9; i_index
++)
{
for (size_t j_index
=
0; j_index
<
10; j_index
++)
{……
差異在循環內部的算法編寫,以學號為例。首先通過畫線,來判斷並調整手工測量的結果:
line(matNumber, cv
:
:Point(i_index
*x_step,
0), cv
:
:Point(i_index
*x_step, matNumber.rows
-
1), cv
:
:Scalar(
0,
0,
255));
line(matNumber, cv
:
:Point(
0,
50
+ j_index
* y_step), cv
:
:Point(matNumber.cols
-
1,
50
+ j_index
* y_step), cv
:
:Scalar(
0,
0,
255));
而后可以具體識別,同樣通過可視化的方式進行初步檢測:
for (size_t i_index
=
0; i_index
<
9; i_index
++)
{
int maxBlob
=
-
1;
int maxindex
=
-
1;
for (size_t j_index
=
0; j_index
<
10; j_index
++)
{
/*line(matNumber, cv::Point(i_index*x_step, 0), cv::Point(i_index*x_step, matNumber.rows - 1), cv::Scalar(0, 0, 255));
line(matNumber, cv::Point(0, 50 + j_index * y_step), cv::Point(matNumber.cols - 1, 50 + j_index * y_step), cv::Scalar(0, 0, 255));*/
Mat tmp
= matNumber(Rect(i_index
*x_step,
50
+ j_index
* y_step, x_step
-
1, y_step
-
1));
Mat tmpGray; Mat tmpBin;
cvtColor(tmp, tmpGray, COLOR_BGR2GRAY);
threshold(tmpGray,tmpBin,
100,
255, THRESH_BINARY_INV);
int tmpBlob
= countNonZero(tmpBin);
//StudentNo[i_index][j_index] = tmpBlob;
if (maxBlob
< tmpBlob)
{
maxBlob
= tmpBlob;
maxindex
= j_index;
}
char cbuf[
255];
sprintf_s(cbuf,
"%d", tmpBlob);
putText(matNumber, cbuf, Point(i_index
*x_step,
50
+ j_index
*y_step), FONT_HERSHEY_PLAIN,
1.0f, Scalar(
0,
0,
255));
}
printf_s(
"%d", maxindex);
}
在小批量的數據上測試可行,證明算法思路初步正確,可以繼續進行下一步研究。這里需要注意的是對於學號來說,使用雙重循環,分別對應列數和填圖的號碼。
但是多選題來說,我建議使用3重循環。
從框架上來說就是這樣:
for (size_t i_index
=
0; i_index
<
4; i_index
++)
{
for (size_t j_index
=
0; j_index
<
4; j_index
++)
{
int maxBlob
=
-
1;
int maxindex
=
-
1;
//line(matChooseOne, cv::Point(0, 13 + j_index * y_step), cv::Point(matChooseOne.cols - 1, 13+j_index * y_step), cv::Scalar(0, 0, 255));
for (size_t blob_index
=
0;blob_index
<
4;blob_index
++)
{……
在識別多選題這塊,細節有所改變:
Mat tmp
= matChooseMore(Rect(
54
+ i_index
*
197
+ blob_index
* x_step,
11
+ j_index
* y_step, x_step, y_step));
Mat tmpGray; Mat tmpBin;
cvtColor(tmp, tmpGray, COLOR_BGR2GRAY);
threshold(tmpGray, tmpBin,
100,
255, THRESH_BINARY_INV);
int tmpBlob
= countNonZero(tmpBin);
if (tmpBlob
>
100)
{
printf_s(
"%s", strConvert(blob_index));
}
四、算法實現
/////////////////////////////////識別學號////////////////////////////////////////////////
int x_step
= matNumber.cols
/
9;
int y_step
= (matNumber.rows
-
50)
/
10;
printf_s(
"學號:");
for (size_t i_index
=
0; i_index
<
9; i_index
++)
{
int maxBlob
=
-
1;
int maxindex
=
-
1;
for (size_t j_index
=
0; j_index
<
10; j_index
++)
{
if (DEBUG)
{
line(matNumber, cv
:
:Point(i_index
*x_step,
0), cv
:
:Point(i_index
*x_step, matNumber.rows
-
1), cv
:
:Scalar(
0,
0,
255));
line(matNumber, cv
:
:Point(
0,
50
+ j_index
* y_step), cv
:
:Point(matNumber.cols
-
1,
50
+ j_index
* y_step), cv
:
:Scalar(
0,
0,
255));
}
Mat tmp
= matNumber(Rect(i_index
*x_step,
50
+ j_index
* y_step, x_step
-
1, y_step
-
1));
Mat tmpGray; Mat tmpBin;
cvtColor(tmp, tmpGray, COLOR_BGR2GRAY);
threshold(tmpGray,tmpBin,
100,
255, THRESH_BINARY_INV);
int tmpBlob
= countNonZero(tmpBin);
if (maxBlob
< tmpBlob)
{
maxBlob
= tmpBlob;
maxindex
= j_index;
}
if (DEBUG)
{
char cbuf[
255];
sprintf_s(cbuf,
"%d", tmpBlob);
putText(matNumber, cbuf, Point(i_index
*x_step,
50
+ j_index
* y_step), FONT_HERSHEY_PLAIN,
1.0f, Scalar(
0,
0,
255));
}
}
printf_s(
"%d", maxindex);
}
printf_s(
"\n");
/////////////////////////////////識別單選////////////////////////////////////////////////
cv
:
:imwrite(
"E:/未來項目/智慧校園/result/_"
+ to_string(i_index)
+
"matChooseOne.jpg", matChooseOne);
printf_s(
"單選:");
x_step
=
35;
y_step
=
25;
for (size_t i_index
=
0; i_index
<
4; i_index
++)
{
for (size_t j_index
=
0; j_index
<
4; j_index
++)
{
int maxBlob
=
-
1;
int maxindex
=
-
1;
if (DEBUG)
{
line(matChooseOne, cv
:
:Point(
0,
13
+ j_index
* y_step), cv
:
:Point(matChooseOne.cols
-
1,
13
+j_index
* y_step), cv
:
:Scalar(
0,
0,
255));
}
for (size_t blob_index
=
0;blob_index
<
4;blob_index
++)
{
if (DEBUG)
{
line(matChooseOne, cv
:
:Point(
55
+ i_index
*
195
+ blob_index
* x_step,
0), cv
:
:Point(
55
+ i_index
*
195
+ blob_index
* x_step, matNumber.rows
-
1), cv
:
:Scalar(
0,
0,
255));
}
Mat tmp
= matChooseOne(Rect(
55
+ i_index
*
195
+ blob_index
* x_step,
13
+ j_index
* y_step, x_step, y_step));
Mat tmpGray; Mat tmpBin;
cvtColor(tmp, tmpGray, COLOR_BGR2GRAY);
threshold(tmpGray, tmpBin,
100,
255, THRESH_BINARY_INV);
int tmpBlob
= countNonZero(tmpBin);
if (maxBlob
< tmpBlob)
{
maxBlob
= tmpBlob;
maxindex
= blob_index;
}
if (DEBUG)
{
char cbuf[
255];
sprintf_s(cbuf,
"%d", tmpBlob);
putText(matChooseOne, cbuf, Point(
55
+ i_index
*
195
+ blob_index
* x_step,
13
+ j_index
* y_step), FONT_HERSHEY_PLAIN,
1.0f, Scalar(
0,
0,
255));
}
}
printf_s(
"%s ", strConvert( maxindex));
}
}
printf_s(
"\n");
/////////////////////////////////識別多選////////////////////////////////////////////////
cv
:
:imwrite(
"E:/未來項目/智慧校園/result/_"
+ to_string(i_index)
+
"matChooseMore.jpg", matChooseMore);
printf_s(
"多選:");
x_step
=
35;
y_step
=
25;
for (size_t i_index
=
0; i_index
<
3; i_index
++)
{
for (size_t j_index
=
0; j_index
<
1; j_index
++)
{
int maxBlob
=
-
1;
int maxindex
=
-
1;
if (DEBUG)
{
line(matChooseMore, cv
:
:Point(
0,
11
+ j_index
* y_step), cv
:
:Point(matChooseMore.cols
-
1,
11
+ j_index
* y_step), cv
:
:Scalar(
0,
0,
255));
}
for (size_t blob_index
=
0; blob_index
<
4; blob_index
++)
{
if (DEBUG)
{
line(matChooseMore, cv
:
:Point(
54
+ i_index
*
197
+ blob_index
* x_step,
0), cv
:
:Point(
54
+ i_index
*
197
+ blob_index
* x_step, matNumber.rows
-
1), cv
:
:Scalar(
0,
0,
255));
}
Mat tmp
= matChooseMore(Rect(
54
+ i_index
*
197
+ blob_index
* x_step,
11
+ j_index
* y_step, x_step, y_step));
Mat tmpGray; Mat tmpBin;
cvtColor(tmp, tmpGray, COLOR_BGR2GRAY);
threshold(tmpGray, tmpBin,
100,
255, THRESH_BINARY_INV);
int tmpBlob
= countNonZero(tmpBin);
if (tmpBlob
>
100)
{
printf_s(
"%s", strConvert(blob_index));
}
if (DEBUG)
{
char cbuf[
255];
sprintf_s(cbuf,
"%d", tmpBlob);
putText(matChooseMore, cbuf, Point(
54
+ i_index
*
197
+ blob_index
* x_step,
11
+ j_index
* y_step), FONT_HERSHEY_PLAIN,
1.0f, Scalar(
0,
0,
255));
}
}
printf_s(
" ");
}
}
識別結果:
1
8371610079632028081800
學號:
320210741
單選:c d d c c a a d a d c c c d b b
多選:acd bd bd
2
8371610079632028081800
學號:
320211633
單選:c d c c b a a d b d c c c d b b
多選:b abd d
3
8371610079632028081800
學號:
320211632
單選:c d d c b a a a d d c b c d b b
多選:cd abd bd
4
8371610079632028081800
學號:
320211650
單選:c b c c c a a d b d c c c d b b
多選:cd abcd acd
5
8371610079632028081800
學號:
320211615
單選:c d a c b a a d b d c c c d c b
多選:acd abd bd
6
8371610079632028081800
學號:
320211609
單選:c d d c c a a d d d c c c d b b
多選:acd abd bd
7
8371610079632028081800
學號:
320211642
單選:c a d c b a a a d d c c c d b b
多選:acd abd bd
8
8371610079632028081800
學號:
320211617
單選:c d d c b a a d d d c c c d b b
多選:ad ad bd
9
8371610079632028081800
學號:
320211616
單選:d d d c b a a d c d c c c a b b
多選:acd ad bcd
10
8371610079632028081800
學號:
320211610
單選:c d d c c a a d d d c c c d b b
多選:acd ad bd
11
8371610079632028081800
學號:
320211622
單選:c d d c b a a d b d c b c a b b
多選:d abd b
12
8371610079632028081800
學號:
320211026
單選:c b b c b a a a d d c c c d a b
多選:ad ad bd
13
8371610079632028081800
學號:
320211040
單選:c b a c c a a c b d c c c d a a
多選:b abd b
14
8371610079632028081800
學號:
320211029
單選:d b d c b a a d a d c c c d b b
多選:cd abd bd
15
8371610079632028081800
學號:
320211025
單選:c d d c b a a d a d c c c d b b
多選:cd d cd
16
8371610079632028081800
學號:
320211032
單選:c c b b a a a d c d c c c d b b
多選:ad ad bd
17
8371610079632028081800
學號:
320211028
單選:c b d c b a b d d d c c c b a b
多選:acd ad bd
18
8371610079632028081800
學號:
320211010
單選:c b d c b a a d b d c c c d b b
多選:acd abd bd
19
8371610079632028081800
學號:
320211004
單選:c b d c c a a d d d c d c d b b
多選:ad ad bd
20
8371610079632028081800
學號:
320211039
單選:d b d c b a a d d d c c c b b b
多選:cd abd bd
21
8371610079632028081800
學號:
320211018
單選:d b d c b a a d a d c a c d b b
多選:cd abd bd
22
8371610079632028081800
學號:
320211052
單選:c d d c c b a d b d c c c d b b
多選:cd ad bd
23
8371610079632028081800
學號:
320211012
單選:c d d c b a a d b d c c c b b b
多選:ad bd bd
24
8371610079632028081800
學號:
320211024
單選:c d d c c a a d a d c c c d b a
多選:acd abd bd
25
8371610079632028081800
學號:
320211036
單選:d d d c b a a c b a c c c a b b
多選:ad ad bd
26
8371610079632028081800
學號:
320211049
單選:d d d c c a a d a b c c c b a b
多選:c acd bcd
27
8371610079632028081800
學號:
320211047
單選:c d d c b a a d b d c c c b b b
多選:d ad bd
28
8371610079632028081800
學號:
320211053
單選:c d d c b a c c a d c c c d b b
多選:bcd cd bd
29
8371610079632028081800
學號:
320211005
單選:d b d c b a a a c d c c c b b a
多選:acd abd bd
學號:
320211005
單選:d b d c b a a a c d c c c b b a
多選:acd abd bd
30
8371610079632028081800
31
8371610079632028081800
學號:
320211045
單選:d d d c b a a d b d c d c d b a
多選:bd cd bd
32
8371610079632028081800
學號:
320211007
單選:d b d c b a a a a d c c b b b a
多選:acd abd bcd
33
8371610079632028081800
學號:
320211037
單選:c b d c b a d a d d c a c a a b
多選:cd ab bd
34
8371610079632028081800
學號:
320211046
單選:d d a c b a a d c d c c c a a b
多選:c bd b
35
8371610079632028081800
學號:
320211035
單選:b b d c b a a d d d c b d a b b
多選:cd b b
36
8371610079632028081800
學號:
320210718
單選:c d d c c a a d b d c c c a b b
多選:ac abd bd
37
8371610079632028081800
學號:
320210705
單選:c d d c c a a d b d c c c d b b
多選:acd abd bd
38
8371610079632028081800
學號:
320210742
單選:d a d c b a a d d d c c c d b b
多選:acd abd bd
39
8371610079632028081800
學號:
320210755
單選:c a d c b a a d b d c c c d b b
多選:c abcd bd
40
8371610079632028081800
學號:
320210747
單選:c d a c b b a d d d c c c d b b
多選:cd ab bd
41
8371610079632028081800
學號:
320210730
單選:c d b c b a a d b d c c c d b b
多選:ad abd bd
42
8371610079632028081800
學號:
320210727
單選:c b d c c a a d b c c c c d b b
多選:d abd cd
43
8371610079632028081800
學號:
320210750
單選:c d b c b a b d b a c c c b b b
多選:ad abcd bd
44
8371610079632028081800
學號:
320210710
單選:c d b c b a a d a d c c c d b d
多選:acd abd bcd
45
8371610079632028081800
學號:
320210706
單選:c d d c b a a d d d c c c d b b
多選:ad abd bd
46
8371610079632028081800
學號:
320210702
單選:c d b c b a a d b d c c c b b b
多選:acd abd bd
47
8371610079632028081800
學號:
320210749
單選:c d c c b a a d b d c c c b b b
多選:bc abd bd
48
8371610079632028081800
學號:
320210719
單選:c d b c b a a d d d c b c b b b
多選:acd abd bd
49
8371610079632028081800
學號:
320210726
單選:c d b c b a a d b d c c c d b b
多選:c abd bd
50
8371610079632028081800
學號:
320210701
單選:c d d c b b a d b d c c c d b b
多選:ad abd bd
51
8371610079632028081800
學號:
320210714
單選:c d d c b a a d a d c c c d b b
多選:acd bd bd
52
8371610079632028081800
學號:
320210709
單選:c b b c b a a d d d c c c d b b
多選:cd abd bd
53
8371610079632028081800
學號:
320210733
單選:c d d c b a a d b d c c d d b b
多選:acd abcd bcd
54
8371610079632028081800
學號:
320210707
單選:d d d c a a a d d c c c d b b b
多選:acd d bd
55
8371610079632028081800
學號:
320210744
單選:c d d c b a a d b d c c c d b b
多選:acd abd bd
56
8371610079632028081800
學號:
320210736
單選:c d d c b a a d d d c c c d b b
多選:bc abd cd
57
8371610079632028081800
學號:
320210751
單選:b d c c b a a d d d c c c d b b
多選:acd abd bd
58
8371610079632028081800
學號:
320210716
單選:c d d c b a a d b d c c d d b b
多選:acd abd bd
59
8371610079632028081800
學號:
320210729
單選:c b b c b a a d a d c c c d b b
多選:acd ab bcd
60
8371610079632028081800
學號:
320210723
單選:c d a c b a a a d d c c c d b b
多選:acd acd bcd
61
8371610079632028081800
學號:
320210703
單選:c d d c b a a b b d c c c d b c
多選:abd ab bd
62
8371610079632028081800
學號:
320210740
單選:c d d c b b a b b d c c c d b b
多選:acd abd bd
63
8371610079632028081800
學號:
320210748
單選:c d d c b a a b d d d c c d b b
多選:cd abd cd
64
8371610079632028081800
學號:
320210721
單選:c d b c b a a d b d c c c a b b
多選:acd abd bd
65
8371610079632028081800
學號:
320210754
單選:d d d c b a a d d d c c c d b b
多選:c abd bd
五、小結和擴展
從目前的結果來看,是能夠解決當前問題的。但是答題卡項目的難點在於模板的定制以及對於采集質量不好情況的處理,所以這里提到的方法只能作為基礎資料進行參考。
附件列表