熟悉opencv的朋友都知道opencv可以用來識別很多東西,今天我們就以基本的數字識別來探索opencv的識別之路。
大致的步驟如下:
(1)首先要載入一幅含有數字的,並對它進行二值化。
(2)尋找數字的大致輪廓。
(3)對找到的數字輪廓按照輸入的順序進行排序。
(4)根據上一步找到的順序對數字輪廓進行分割,將單個數字輪廓提取出來。
(5)模板匹配
1、二值化處理
mat srcimage=imread("e://pictured");
imshow(''原圖",srcimage);
mat grayimage,binimage;
cvtcolor(srcimage,grayimage,color_bgr2gray);
threshold(grayimage,binimage,100,255,cv_thresh_binary_inv);//這個cv_thresh_binary_inv引數的選擇是根據輸入的數字顏色和背景顏色決定的。
2、尋找數字的輪廓
mat conimage = mat::zeros(binimage.size(), binimage.type());//尋找輪廓,必須指定為尋找外部輪廓。目的是為了限定乙個數字只有乙個輪廓。
vector> contours;
vectorhierarchy;
drawcontours(conimage, contours, -1, 255);//繪製輪廓
3、對找到的輪廓進行排序
(1)定義乙個新的rect類,存放輪廓的外接矩形方便接下來的排序
class rect
public:
rect(){}
~rect(){}
rect(rect &temp):rc(temp){} //比較矩形左上角的橫座標,以便排序
bool operator<(rect &rect)
if (this->rc.x < rect.rc.x)
return true;
else
return false;
} //過載賦值運算子
rect operator=(rect &rect)
this->rc = rect.rc;
return *this;
} //獲取矩形
rect getrect()
return rc;
private: rect rc;//存放矩形
(2)氣泡排序法
for (int i = 0; i < sort_rect.size(); i++) //對矩形進行排序找到數字的排列順序
for (int j = i + 1; j < sort_rect.size(); j++)
if (sort_rect[j] < sort_rect[i])
rect temp = sort_rect[j];
sort_rect[j] = sort_rect[i];
sort_rect[i] = temp;
4、初始化數字模板
5、數字分割
vectormyroi; //按順序取出和分割數字
for (int i = 0; i < sort_rect.size(); i++)
mat roi;
roi = conimage(sort_rect[i].getrect());
mat dstroi = mat::zeros(mytemplate[0].size(),mytemplate[0].type());
resize(roi, dstroi, mytemplate[0].size(), 0, 0, inter_nearest);
myroi.push_back(dstroi);
6、模板匹配
(1)首先進行比較,使用adsdiff計算模板和待識別數字的差值,差值最小的即為最匹配的數字,
int getpiexsum(mat &image)//求的畫素和
int sum = 0;
for (int i = 0; i < image.cols; i++)
for (int j = 0; j < image.rows; j++)
sum += image.at(j, i);
return sum;
(2)匹配結果並輸出
vectorseq;//順序存放識別結果
for (int i = 0; i < myroi.size(); i++)
mat subimage;
int sum = 0;
int min = 100000;
int min_seq = 0;//記錄最小的和對應的數字
for (int j = 0; j < 10; j++)
absdiff(myroi[i], mytemplate[j], subimage); //計算兩個的差值
sum = getpiexsum(subimage);
if (sum < min)
min = sum;
min_seq = j;
sum = 0;
seq.push_back(min_seq);
} //輸出結果
cout << "識別結果為:";
for (int i = 0; i < seq.size(); i++)
cout << seq[i];
cout << endl;
存在的問題與不足:發現有很多影響準確率的因素,例如數字顏色與背景顏色,要識別的字型的大小與控制台輸出字型大小的差異。
opencv 顏色識別
include include opencv2 highgui highgui.hpp include opencv2 imgproc imgproc.hpp using namespace cv using namespace std int main int argc,char argv nam...
OpenCv人臉識別
在進行人臉識別時候,為了達到效果,我們使用opencv的分類器。進行對進行識別。include include include include using namespace cv using namespace std void detectanddraw mat img,cascadeclass...
OpenCV顏色識別
hsv模型中顏色的引數分別是 色調 h hue 飽和度 s saturation 亮度 v value 由a.r.smith在1978年建立的一種顏色空間,也稱六角錐體模型 hexcone model 設 r,g,b 分別是乙個顏色的紅 綠和藍座標,它們的值是在 0 到 1 之間的實數。設 max ...