圖片上的數字識別
阿新 • • 發佈:2019-02-10
步驟:
1.影象分割->製作模板;
2.目標圖片分割->比對識別;
#include <stdio.h> #include <stdlib.h> #include <opencv\cv.hpp> #include <opencv2\opencv.hpp> #include <iostream> #include <fstream> #include <Windows.h> using namespace cv; using namespace std; int getColSum(Mat src,int col) { int sum = 0; int height = src.rows; int width = src.cols; for (int i = 0; i < height; i++) { sum = sum + src.at <uchar>(i, col); } return sum; } int getRowSum(Mat src, int row) { int sum = 0; int height = src.rows; int width = src.cols; for (int i = 0; i < width; i++) { sum += src.at <uchar>(row, i); } return sum; } void cutTop(Mat& src, Mat& dstImg)//上下切割 { int top, bottom; top = 0; bottom = src.rows; int i; for (i = 0; i < src.rows; i++) { int colValue = getRowSum(src, i); //cout <<i<<" th "<< colValue << endl; if (colValue>0) { top = i; break; } } for (; i < src.rows; i++) { int colValue = getRowSum(src, i); //cout << i << " th " << colValue << endl; if (colValue == 0) { bottom = i; break; } } int height = bottom - top; Rect rect(0, top, src.cols, height); dstImg = src(rect).clone(); } int cutLeft(Mat& src, Mat& leftImg, Mat& rightImg)//左右切割 { int left, right; left = 0; right = src.cols; int i; for (i = 0; i < src.cols; i++) { int colValue = getColSum(src, i); //cout <<i<<" th "<< colValue << endl; if (colValue>0) { left = i; break; } } if (left == 0) { return 1; } for (; i < src.cols; i++) { int colValue = getColSum(src, i); //cout << i << " th " << colValue << endl; if (colValue == 0) { right = i; break; } } int width = right - left; Rect rect(left, 0, width, src.rows); leftImg = src(rect).clone(); Rect rectRight(right, 0, src.cols - right, src.rows); rightImg = src(rectRight).clone(); cutTop(leftImg, leftImg); return 0; } void getPXSum(Mat &src, int &a)//獲取所有畫素點和 { threshold(src, src, 100, 255, CV_THRESH_BINARY); a = 0; for (int i = 0; i < src.rows;i++) { for (int j = 0; j < src.cols; j++) { a += src.at <uchar>(i, j); } } } int getSubtract(Mat &src, int TemplateNum) //兩張圖片相減 { Mat img_result; int min = 10000000; int serieNum = 0; for (int i = 0; i < TemplateNum; i++){ char name[20]; sprintf_s(name, "D:\\%dLeft.jpg", i); Mat Template = imread(name, CV_LOAD_IMAGE_GRAYSCALE); threshold(Template, Template, 200, 255, CV_THRESH_BINARY); threshold(src, src, 80, 255, CV_THRESH_BINARY); resize(src, src, Size(32, 48), 0, 0, CV_INTER_LINEAR); resize(Template, Template, Size(32, 48), 0, 0, CV_INTER_LINEAR); //imshow(name, Template); absdiff(Template, src, img_result); int diff = 0; getPXSum(img_result, diff); if (diff < min) { min = diff; serieNum = i; } } if(serieNum!=10) { /* printf("最小距離是%d ", min); printf("匹配到第%d個模板匹配的數字是%d\n", serieNum,serieNum);*/ cout<<serieNum; } return serieNum; } int main() { clock_t startTime,mattime,endTime; startTime = clock(); RECT rc; HWND hwnd = FindWindow(NULL,TEXT("開獎資料-北京時時彩")); //注意視窗不能最小化 if (hwnd == NULL) { cout << "找不到視窗" << endl; return 0; } GetClientRect(hwnd, &rc); //建立空點陣圖 HDC hdcScreen = GetDC(NULL); HDC hdc = CreateCompatibleDC(hdcScreen); HBITMAP hbmp = CreateCompatibleBitmap(hdcScreen, rc.right - rc.left, rc.bottom - rc.top); SelectObject(hdc, hbmp); //得到目標視窗點陣圖 PrintWindow(hwnd, hdc, PW_CLIENTONLY); BITMAP bm;//影象資訊; GetObject(hbmp, sizeof(bm), (LPSTR)&bm); //把bmp影象轉為Mat型別進行opencv的函式操作; Mat dst; dst.create(cvSize(bm.bmWidth,bm.bmHeight),CV_8UC4); GetBitmapBits(hbmp,bm.bmWidth*bm.bmHeight*4,dst.data); cvtColor(dst,dst,CV_BGRA2BGR); imshow("cap",dst); //釋放dc DeleteDC(hdc); DeleteObject(hbmp); ReleaseDC(NULL, hdcScreen); cout<<"開獎資料識別結果:"<<endl; int roiheight=bm.bmHeight-125; for(int k=0;k<roiheight/33;k++)//roiheight/33 { mattime=clock(); Rect re(210,125+k*33,100,30); Mat src(dst,re); imshow("roi",src); cvtColor(src,src,CV_BGR2GRAY); //Mat src = imread("D:\\1.bmp", CV_LOAD_IMAGE_GRAYSCALE); threshold(src, src, 100 , 255, CV_THRESH_BINARY); //adaptiveThreshold(src, src, 255, CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY_INV, 31,0); bitwise_not(src,src); imshow("origin", src); //imwrite("d:\\sa.bmp",src); Mat leftImg,rightImg; int res = cutLeft(src, leftImg, rightImg); int i = 0; while (res == 0) { //製作樣本// /* char nameLeft[10]; sprintf(nameLeft, "%dLeft", i); char nameRight[10]; sprintf(nameRight, "%dRight", i); i++; imshow(nameLeft, leftImg); stringstream ss; ss << nameLeft; imwrite("D:\\" + ss.str() + ".jpg", leftImg); ss >> nameLeft;*/ //檢測// Mat srcTmp = rightImg; getSubtract(leftImg, 11); res = cutLeft(srcTmp, leftImg, rightImg); } cout<<endl; } endTime = clock(); cout<<"影象處理時間"<<(double)(mattime - startTime) / CLOCKS_PER_SEC<<"s"<<endl; cout << "Totle Time : " <<(double)(endTime - startTime) / CLOCKS_PER_SEC << "s" << endl; waitKey(0); return 0; }