处理票据识别的预处理

#include<iostream>
#include<opencv.hpp>
using namespace cv;
using namespace std;
void chao_thinimage(Mat &srcimage)//单通道、二值化后的图像
{
    vector<Point> deletelist1;
    int Zhangmude[9];
    int nl = srcimage.rows;
    int nc = srcimage.cols;
    while (true)
    {
        for (int j = 1; j < (nl - 1); j++)
        {
            uchar* data_last = srcimage.ptr<uchar>(j - 1);
            uchar* data = srcimage.ptr<uchar>(j);
            uchar* data_next = srcimage.ptr<uchar>(j + 1);
            for (int i = 1; i < (nc - 1); i++)
            {
                if (data[i] == 255)
                {
                    Zhangmude[0] = 1;
                    if (data_last[i] == 255) Zhangmude[1] = 1;
                    else  Zhangmude[1] = 0;
                    if (data_last[i + 1] == 255) Zhangmude[2] = 1;
                    else  Zhangmude[2] = 0;
                    if (data[i + 1] == 255) Zhangmude[3] = 1;
                    else  Zhangmude[3] = 0;
                    if (data_next[i + 1] == 255) Zhangmude[4] = 1;
                    else  Zhangmude[4] = 0;
                    if (data_next[i] == 255) Zhangmude[5] = 1;
                    else  Zhangmude[5] = 0;
                    if (data_next[i - 1] == 255) Zhangmude[6] = 1;
                    else  Zhangmude[6] = 0;
                    if (data[i - 1] == 255) Zhangmude[7] = 1;
                    else  Zhangmude[7] = 0;
                    if (data_last[i - 1] == 255) Zhangmude[8] = 1;
                    else  Zhangmude[8] = 0;
                    int whitepointtotal = 0;
                    for (int k = 1; k < 9; k++)
                    {
                        whitepointtotal = whitepointtotal + Zhangmude[k];
                    }
                    if ((whitepointtotal >= 2) && (whitepointtotal <= 6))
                    {
                        int ap = 0;
                        if ((Zhangmude[1] == 0) && (Zhangmude[2] == 1)) ap++;
                        if ((Zhangmude[2] == 0) && (Zhangmude[3] == 1)) ap++;
                        if ((Zhangmude[3] == 0) && (Zhangmude[4] == 1)) ap++;
                        if ((Zhangmude[4] == 0) && (Zhangmude[5] == 1)) ap++;
                        if ((Zhangmude[5] == 0) && (Zhangmude[6] == 1)) ap++;
                        if ((Zhangmude[6] == 0) && (Zhangmude[7] == 1)) ap++;
                        if ((Zhangmude[7] == 0) && (Zhangmude[8] == 1)) ap++;
                        if ((Zhangmude[8] == 0) && (Zhangmude[1] == 1)) ap++;
                        if (ap == 1)
                        {
                            if ((Zhangmude[1] * Zhangmude[7] * Zhangmude[5] == 0) && (Zhangmude[3] * Zhangmude[5] * Zhangmude[7] == 0))
                            {
                                deletelist1.push_back(Point(i, j));
                            }
                        }
                    }
                }
            }
        }
        if (deletelist1.size() == 0) break;
        for (size_t i = 0; i < deletelist1.size(); i++)
        {
            Point tem;
            tem = deletelist1[i];
            uchar* data = srcimage.ptr<uchar>(tem.y);
            data[tem.x] = 0;
        }
        deletelist1.clear();

        for (int j = 1; j < (nl - 1); j++)
        {
            uchar* data_last = srcimage.ptr<uchar>(j - 1);
            uchar* data = srcimage.ptr<uchar>(j);
            uchar* data_next = srcimage.ptr<uchar>(j + 1);
            for (int i = 1; i < (nc - 1); i++)
            {
                if (data[i] == 255)
                {
                    Zhangmude[0] = 1;
                    if (data_last[i] == 255) Zhangmude[1] = 1;
                    else  Zhangmude[1] = 0;
                    if (data_last[i + 1] == 255) Zhangmude[2] = 1;
                    else  Zhangmude[2] = 0;
                    if (data[i + 1] == 255) Zhangmude[3] = 1;
                    else  Zhangmude[3] = 0;
                    if (data_next[i + 1] == 255) Zhangmude[4] = 1;
                    else  Zhangmude[4] = 0;
                    if (data_next[i] == 255) Zhangmude[5] = 1;
                    else  Zhangmude[5] = 0;
                    if (data_next[i - 1] == 255) Zhangmude[6] = 1;
                    else  Zhangmude[6] = 0;
                    if (data[i - 1] == 255) Zhangmude[7] = 1;
                    else  Zhangmude[7] = 0;
                    if (data_last[i - 1] == 255) Zhangmude[8] = 1;
                    else  Zhangmude[8] = 0;
                    int whitepointtotal = 0;
                    for (int k = 1; k < 9; k++)
                    {
                        whitepointtotal = whitepointtotal + Zhangmude[k];
                    }
                    if ((whitepointtotal >= 2) && (whitepointtotal <= 6))
                    {
                        int ap = 0;
                        if ((Zhangmude[1] == 0) && (Zhangmude[2] == 1)) ap++;
                        if ((Zhangmude[2] == 0) && (Zhangmude[3] == 1)) ap++;
                        if ((Zhangmude[3] == 0) && (Zhangmude[4] == 1)) ap++;
                        if ((Zhangmude[4] == 0) && (Zhangmude[5] == 1)) ap++;
                        if ((Zhangmude[5] == 0) && (Zhangmude[6] == 1)) ap++;
                        if ((Zhangmude[6] == 0) && (Zhangmude[7] == 1)) ap++;
                        if ((Zhangmude[7] == 0) && (Zhangmude[8] == 1)) ap++;
                        if ((Zhangmude[8] == 0) && (Zhangmude[1] == 1)) ap++;
                        if (ap == 1)
                        {
                            if ((Zhangmude[1] * Zhangmude[3] * Zhangmude[5] == 0) && (Zhangmude[3] * Zhangmude[1] * Zhangmude[7] == 0))
                            {
                                deletelist1.push_back(Point(i, j));
                            }
                        }
                    }
                }
            }
        }
        if (deletelist1.size() == 0) break;
        for (size_t i = 0; i < deletelist1.size(); i++)
        {
            Point tem;
            tem = deletelist1[i];
            uchar* data = srcimage.ptr<uchar>(tem.y);
            data[tem.x] = 0;
        }
        deletelist1.clear();
    }
}
//subfunction
bool cmpy_y(cv::Point const& a, cv::Point const& b)
{
    return a.y < b.y;
}
bool cmpy_x(cv::Point const& a, cv::Point const& b)
{
    return a.x < b.x;
}
int main()
{
    cout << "hello world" << endl;
    Mat srcImg = imread("E:\\fengce\\TEST\\9.tif");
    Mat dstImg;
    cvtColor(srcImg,dstImg,CV_BGR2GRAY);
    Mat bw;
    adaptiveThreshold(~dstImg, bw, 255, CV_ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 15, -2);
//  chao_thinimage(bw);
    imshow("bw", bw);
    Mat horizontal = bw.clone();
    Mat vertical = bw.clone();

    int scale = 20; //这个值越大,检测到的直线越多
    int horizontalsize = horizontal.cols / scale;

    // 为了获取横向的表格线,设置腐蚀和膨胀的操作区域为一个比较大的横向直条
    Mat horizontalStructure = getStructuringElement(MORPH_RECT, Size(horizontalsize, 1));

    // 先腐蚀再膨胀
    erode(horizontal, horizontal, horizontalStructure, Point(-1, -1));
    dilate(horizontal, horizontal, horizontalStructure, Point(-1, -1));
    //imshow("horizontal", horizontal);

    int verticalsize = vertical.rows / scale;
    Mat verticalStructure = getStructuringElement(MORPH_RECT, Size(1, verticalsize));
    erode(vertical, vertical, verticalStructure, Point(-1, -1));
    dilate(vertical, vertical, verticalStructure, Point(-1, -1));
    //imshow("vertical", vertical);

    Mat mask = horizontal + vertical;
    imshow("mask", mask);

    chao_thinimage(horizontal);
    chao_thinimage(vertical);
    Mat joints;
    bitwise_and(horizontal, vertical, joints);


    vector<Point> temp;
    vector<Point> endtemp;
    Point start;
    //寻找左上角点
    for (int i = 0; i < joints.rows; i++)
    {
        uchar *data = joints.ptr<uchar>(i);
        for (int j = 0; j < joints.cols; j++)
        {
            if (data[j] == 255 && data[j - 1] == 0)
            {
                start.x = j;
                start.y = i;
                temp.push_back(start);
                endtemp.push_back(start);
            }
        }
    }
    sort(temp.begin(), temp.end(), cmpy_x);
    sort(endtemp.begin(),endtemp.end(), cmpy_y);
    for (int j = 0; j < temp.size(); j++)
    {
        cout << temp[j]<< endl;
    }
    cout << "y=" << endl;
    for (int j = 0; j < endtemp.size(); j++)
    {
        cout << endtemp[j] << endl;
    }
    int x0 = temp[0].x+2;
    int y0 = temp[0].y+2;
    int width = temp[temp.size() - 1].x - temp[0].x-2;
    int height = endtemp[endtemp.size() - 1].y - endtemp[0].y-2;
    if (width <= srcImg.cols - x0 && height <= srcImg.rows - y0)
    {
        Mat ROI(srcImg, Rect(x0, y0, width, height));
        imshow("ROI", ROI);
    }
    else
    {
        cout << "获取失败" << endl;
    }
    //寻找右下角的点
    //imwrite("joints.tif",joints);
    imshow("joints", joints);
    imshow("src", srcImg);
    //cout << start << endl;
    waitKey(0);
    return 0;
}

欢迎交流

猜你喜欢

转载自blog.csdn.net/qq_34510308/article/details/81018490