1. 程式人生 > >使用Opencv+VS2015做數字影象識別

使用Opencv+VS2015做數字影象識別

一、首先建立數字的模板(0-9)影象
這裡寫圖片描述
使用Windows自帶的畫圖軟體,製作數字圖片這裡寫圖片描述
依次類推建立數字0-9的圖片
這裡寫圖片描述
把圖片就放在工程目錄下,如上圖。
二、完整程式碼如下

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

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 = 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); if
(colValue > 0) { top = i; break; } } for (; i < src.rows; i++) { int colValue = getRowSum(src, i); 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); if (colValue > 0) { left = i; break; } } if (left == 0) { return 1; } for (; i < src.cols; i++) { int colValue = getColSum(src, i); 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 = 1000000; int serieNum = 0; for (int i = 0; i <= TemplateNum; i++) { char name[20]; sprintf_s(name, "%d.png", i); Mat Template = imread(name, CV_LOAD_IMAGE_GRAYSCALE); threshold(Template, Template, 100, 255, CV_THRESH_BINARY); threshold(src, src, 100, 255, CV_THRESH_BINARY); resize(src, src, Size(50, 50), 0, 0, CV_INTER_LINEAR); resize(Template, Template, Size(50, 50), 0, 0, CV_INTER_LINEAR); absdiff(Template, src, img_result); int diff = 0; getPXSum(img_result, diff); if (diff < min) { min = diff; serieNum = i; } } printf("最小距離是%d", min); printf("匹配到第%d個模板匹配的數字是%d\n", serieNum, serieNum); return serieNum; } int main() { //用於模板建立 for (int i = 0; i < 10; i++) { char fileName[10]; sprintf_s(fileName, "%d.png", i); Mat src = imread(fileName, CV_LOAD_IMAGE_GRAYSCALE); threshold(src, src, 100, 255, CV_THRESH_BINARY_INV); Mat rImg,dst; cutLeft(src, dst, rImg); imwrite(fileName, dst); } //用於識別 //Mat src = imread("z.png", CV_LOAD_IMAGE_GRAYSCALE); //threshold(src, src, 100, 255, CV_THRESH_BINARY_INV); //imshow("origin", src); //Mat leftImg, rightImg; //int res = cutLeft(src, leftImg, rightImg); //while (res == 0) //{ // Mat srcTmp = rightImg; // getSubtract(leftImg, 9); // res = cutLeft(srcTmp, leftImg, rightImg); //} waitKey(0); return 0; }

三、模板建立
使用上面程式碼執行獲得數字的模板,如圖
這裡寫圖片描述
四、識別
將main函式中用於模板建立的程式碼註釋掉,用於識別的程式碼去掉註釋

  int main()
{
    //用於模板建立
    //for (int i = 0; i < 10; i++)
    //{
    //  char fileName[10];
    //  sprintf_s(fileName, "%d.png", i);
    //  Mat src = imread(fileName, CV_LOAD_IMAGE_GRAYSCALE);
    //  threshold(src, src, 100, 255, CV_THRESH_BINARY_INV);
    //  Mat rImg,dst;
    //  cutLeft(src, dst, rImg);
    //  imwrite(fileName, dst);
    //}


    //用於識別
    Mat src = imread("z.png", CV_LOAD_IMAGE_GRAYSCALE);
    threshold(src, src, 100, 255, CV_THRESH_BINARY_INV);
    imshow("origin", src);
    Mat leftImg, rightImg;
    int res = cutLeft(src, leftImg, rightImg);
    while (res == 0)
    {
        Mat srcTmp = rightImg;
        getSubtract(leftImg, 9);
        res = cutLeft(srcTmp, leftImg, rightImg);
    }

    waitKey(0);
    return 0;
}  

用畫圖軟體製作識別用的影象
這裡寫圖片描述
執行程式結果如下:
這裡寫圖片描述