刘家伟程序备份1(主要参考点:分割部分以及保存,在图片上显示数字)

102 篇文章 30 订阅
52 篇文章 2 订阅

今天成功代码暂存。该程序实现了轮廓检测,矩形分割出轮廓,模板匹配后,并显示数字

主函数




#include "stdafx.h"
#include <cv.h> 
#include "putText.h"

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"


//-----------------------------------【命名空间声明部分】--------------------------------------
//          描述:包含程序所使用的命名空间
//-----------------------------------------------------------------------------------------------
using namespace cv;
using namespace std;
//
//-----------------------------------【宏定义部分】-------------------------------------------- 
//  描述:定义一些辅助宏 
//------------------------------------------------------------------------------------------------ 
#define WINDOW_NAME1 "【原始图窗口】"        //为窗口标题定义的宏 
#define WINDOW_NAME2 "【效果图窗口】"        //为窗口标题定义的宏 

#define WINDOW_NAME11 "【原始图片】"        //为窗口标题定义的宏 
#define WINDOW_NAME21 "【匹配窗口】"        //为窗口标题定义的宏 
//-----------------------------------【全局变量声明部分】--------------------------------------
//  描述:全局变量的声明
//-----------------------------------------------------------------------------------------------
Mat g_srcImage;
Mat g_srcImage1;
Mat g_grayImage;
cv::Mat org;
cv::Mat dst;
int g_nThresh = 50;//阈值
int g_nMaxThresh = 255;//阈值最大值
RNG g_rng(12345);//随机数生成器
char strangerName[360];
int g_nMatchMethod;
int g_nMaxTrackbarNum = 5;
//-----------------------------------【全局函数声明部分】--------------------------------------
//   描述:全局函数的声明
//-----------------------------------------------------------------------------------------------
void on_ContoursChange(int, void*);
void on_Matching(int, void*);
static void ShowHelpText();
Mat g_templateImage; Mat g_resultImage;
//-----------------------------------【main( )函数】--------------------------------------------
//   描述:控制台应用程序的入口函数,我们的程序从这里开始执行
//-----------------------------------------------------------------------------------------------
int main()
{
    //【0】改变console字体颜色
    system("color 1F");




    //【0】显示欢迎和帮助文字
    ShowHelpText();

    //【1】载入3通道的原图像
    g_srcImage = imread("010.jpg", 1);
    g_srcImage1 = imread("777.jpg", 1);
    if (!g_srcImage.data) { printf("读取图片错误,请确定目录下是否有imread函数指定的图片存在~! \n"); return false; }

    //【2】得到原图的灰度图像并进行平滑
    cvtColor(g_srcImage, g_grayImage, CV_BGR2GRAY);
    blur(g_grayImage, g_grayImage, Size(3, 3));

    //【3】创建原始图窗口并显示
    namedWindow(WINDOW_NAME1, CV_WINDOW_AUTOSIZE);
    imshow(WINDOW_NAME1, g_srcImage);
    namedWindow(WINDOW_NAME11, CV_WINDOW_AUTOSIZE);
    namedWindow(WINDOW_NAME21, CV_WINDOW_AUTOSIZE);


    //【4】设置滚动条并调用一次回调函数
    createTrackbar(" 阈值:", WINDOW_NAME1, &g_nThresh, g_nMaxThresh, on_ContoursChange);
    on_ContoursChange(0, 0);

    waitKey(0);

    return(0);
}


//----------------------------【on_ContoursChange( )函数】---------------------------------
//      描述:回调函数
//-------------------------------------------------------------------------------------------------  
void on_ContoursChange(int, void*)
{
    //定义一些参数
    Mat threshold_output;
    vector<vector<Point>> contours;
    vector<Vec4i> hierarchy;
    g_nThresh = 150;
    // 使用Threshold检测边缘
    threshold(g_grayImage, threshold_output, g_nThresh, 255, THRESH_BINARY);

    // 找出轮廓
    findContours(threshold_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));

    // 多边形逼近轮廓 + 获取矩形和圆形边界框
    vector<vector<Point> > contours_poly(contours.size());
    vector<Rect> boundRect(contours.size());
    vector<Point2f>center(contours.size());
    vector<float>radius(contours.size());

    //一个循环,遍历所有部分,进行本程序最核心的操作
    for (unsigned int i = 0; i < contours.size(); i++)
    {
        approxPolyDP(Mat(contours[i]), contours_poly[i], 3, true);//用指定精度逼近多边形曲线 
        boundRect[i] = boundingRect(Mat(contours_poly[i]));//计算点集的最外面(up-right)矩形边界
        minEnclosingCircle(contours_poly[i], center[i], radius[i]);//对给定的 2D点集,寻找最小面积的包围圆形 
    }

    // 绘制多边形轮廓 + 包围的矩形框 + 圆形框
    Mat drawing = Mat::zeros(threshold_output.size(), CV_8UC3);

    Mat image_cut[100];      //从img中按照rect进行切割,此时修改image_cut时image中对应部分也会修改,因此需要copy  
    Mat image_copy[100];   //clone函数创建新的图片 
    int geshu = 0;
    for (int unsigned i = 0; i<contours.size(); i++)
    {
        Scalar color = Scalar(g_rng.uniform(0, 255), g_rng.uniform(0, 255), g_rng.uniform(0, 255));//随机设置颜色
        drawContours(drawing, contours_poly, i, color, 1, 8, vector<Vec4i>(), 0, Point());//绘制轮廓
        Point text_lb;//中点


        //circle(drawing, center[i], (int)radius[i], color, 2, 8, 0);//绘制圆
        //if (radius[i]<39 && radius[i]>20 && center[i].y>300 && center[i].x>200 && center[i].x<400)
        //if (radius[i]<39 && radius[i]>20 && center[i].y>300 && center[i].x>350 && center[i].x<400)
        //中间下面的点
        if (radius[i]<39 && radius[i]>20 && center[i].y>200 && center[i].x>100 && center[i].x<650)
        {
            geshu++;
            rectangle(drawing, boundRect[i].tl(), boundRect[i].br(), color, 2, 8, 0);//绘制矩形
            text_lb = Point((boundRect[i].tl().x + boundRect[i].br().x)*0.5, (boundRect[i].tl().y + boundRect[i].br().y)*0.5);
            //putTextZH(drawing, "中点", center[i], Scalar(0, 0, 255), 10, "Arial");
            int width = abs(boundRect[i].tl().x - boundRect[i].br().x);
            int height = abs(boundRect[i].tl().y - boundRect[i].br().y);



            Rect rect(boundRect[i].tl().x, boundRect[i].tl().y, width, height);   //创建一个Rect框,属于cv中的类,四个参数代表x,y,width,height  

            image_cut[i] = Mat(g_grayImage, rect);      //从img中按照rect进行切割,此时修改image_cut时image中对应部分也会修改,因此需要copy  
            image_copy[i] = image_cut[i].clone();   //clone函数创建新的图片  
            sprintf(strangerName, "数字%d", geshu);
            namedWindow(strangerName, 1);//参数为零,则可以自由拖动strangerName
            imshow(strangerName, image_copy[i]);

            sprintf(strangerName, "E://OCR_Recognition//opencv_project//project_op//opencv2_5_20//baocun_tupian//%d.jpg", geshu);  /*注意修改路径*/
            imwrite(strangerName, image_copy[i]);
            g_templateImage = imread(strangerName, 1);
            //【1】给局部变量初始化
            Mat srcImage22;
            g_srcImage1.copyTo(srcImage22);

            //【2】初始化用于结果输出的矩阵
            int resultImage_cols = g_srcImage1.cols - g_templateImage.cols + 1;
            int resultImage_rows = g_srcImage1.rows - g_templateImage.rows + 1;
            g_resultImage.create(resultImage_cols, resultImage_rows, CV_32FC1);
            //【3】进行匹配和标准化
            g_nMatchMethod = 3;
            matchTemplate(g_srcImage1, g_templateImage, g_resultImage, g_nMatchMethod);
            normalize(g_resultImage, g_resultImage, 0, 1, NORM_MINMAX, -1, Mat());

            //【4】通过函数 minMaxLoc 定位最匹配的位置
            double minValue; double maxValue; Point minLocation; Point maxLocation;
            Point matchLocation;
            minMaxLoc(g_resultImage, &minValue, &maxValue, &minLocation, &maxLocation, Mat());

            //【5】对于方法 SQDIFF 和 SQDIFF_NORMED, 越小的数值有着更高的匹配结果. 而其余的方法, 数值越大匹配效果越好
            if (g_nMatchMethod == CV_TM_SQDIFF || g_nMatchMethod == CV_TM_SQDIFF_NORMED)
            {
                matchLocation = minLocation;
            }
            else
            {
                matchLocation = maxLocation;
            }

            //【6】绘制出矩形,并显示最终结果
            Point liu = Point(matchLocation.x + g_templateImage.cols, matchLocation.y + g_templateImage.rows);
            rectangle(srcImage22, matchLocation, Point(matchLocation.x + g_templateImage.cols, matchLocation.y + g_templateImage.rows), Scalar(0, 0, 255), 2, 8, 0);
            rectangle(g_resultImage, matchLocation, Point(matchLocation.x + g_templateImage.cols, matchLocation.y + g_templateImage.rows), Scalar(0, 0, 255), 2, 8, 0);
            printf(" x( %d , y :%d)\n", matchLocation.x + g_templateImage.cols, matchLocation.y + g_templateImage.rows);
            if (liu.x == 1128 && liu.y == 154)
            {
                putTextZH(drawing, "6", center[i], Scalar(0, 0, 255), 30, "Arial");
            }
            else if (liu.x == 455 && liu.y == 59)
            {
                putTextZH(drawing, "1", center[i], Scalar(0, 0, 255), 30, "Arial");
            }
            else if (liu.x == 736 && liu.y == 59)
            {
                putTextZH(drawing, "2", center[i], Scalar(0, 0, 255), 30, "Arial");
            }
            else if (liu.x == 1261 && liu.y == 154)
            {
                putTextZH(drawing, "6", center[i], Scalar(0, 0, 255), 30, "Arial");
            }
            else if (liu.x == 73 && liu.y == 59)
            {
                putTextZH(drawing, "0", center[i], Scalar(0, 0, 255), 30, "Arial");
            }
            else if (liu.x == 203 && liu.y == 154)
            {
                putTextZH(drawing, "4", center[i], Scalar(0, 0, 255), 30, "Arial");
            }
            else if (liu.x == 991 && liu.y == 59)
            {
                putTextZH(drawing, "3", center[i], Scalar(0, 0, 255), 30, "Arial");
            }
            else if (liu.x == 728 && liu.y == 154)
            {
                putTextZH(drawing, "5", center[i], Scalar(0, 0, 255), 30, "Arial");
            }
            else if (liu.x == 859 && liu.y == 154)
            {
                putTextZH(drawing, "5", center[i], Scalar(0, 0, 255), 30, "Arial");
            }
            else if (liu.x == 597 && liu.y == 59)
            {
                putTextZH(drawing, "2", center[i], Scalar(0, 0, 255), 30, "Arial");
            }
            else if (liu.x == 335 && liu.y == 154)
            {
                putTextZH(drawing, "5", center[i], Scalar(0, 0, 255), 30, "Arial");
            }
            else if (liu.x == 997 && liu.y == 154)
            {
                putTextZH(drawing, "6", center[i], Scalar(0, 0, 255), 30, "Arial");
            }
            imshow(WINDOW_NAME11, srcImage22);
            imshow(WINDOW_NAME21, g_resultImage);

        }
    }

    // 显示效果图窗口
    namedWindow(WINDOW_NAME2, CV_WINDOW_AUTOSIZE);
    imshow(WINDOW_NAME2, drawing);
}

//-----------------------------------【ShowHelpText( )函数】----------------------------------  
//      描述:输出一些帮助信息  
//----------------------------------------------------------------------------------------------  
static void ShowHelpText()
{
    //输出欢迎信息和OpenCV版本
    printf("\n\n\t\t\t数字识别\n");
    printf("\n\n\t\t\t   当前使用的OpenCV版本为:" CV_VERSION);
    printf("\n\n  ----------------------------------------------------------------------------\n");

    //输出一些帮助信息  
    printf("\n\n\n\t当前阈值150~\n\n");
    printf("\n\n\t按键操作说明: \n\n"
        "\t\t键盘按键【ESC】- 退出程序\n\n"
        "\t\t毛哥2018/5/16\n\n");
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

翟羽嚄

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值