如何使用OPENCV从图像中检测特定数量?

时间:2014-04-24 21:09:54

标签: opencv image-processing ocr template-matching

我住在土耳其,在土耳其,电视广告正在进行一些倒计时,告诉我们电视节目或电影开始还有多少分钟。

我想要做的是在柜台上抓住00:59秒或者只是第二个“0”。 alghoritm必须明白“0”是“0”而不是任何其他数字。

之后我尝试了与模板图像匹配的模板,但它也检测到了错误的数字。

所以我无法弄清楚哪种方法最好......

我试图从这些帧中检测到:

sample image 1

sample image 2

因为你看到它检测到“1”而不是“0”。

下面是我的模板匹配代码;

#include<opencv2/highgui/highgui.hpp>
#include <iostream>
#include <stdio.h>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <sstream>
using namespace cv;
using namespace std;

Mat frame;
Mat img; 
Mat templ; 
Mat templ_resized;
Mat templ_resized_bw;
Mat result;
cv::Mat sel;
cv::Mat img_final;
//**************

int main(int argc, char** argv)
{
    VideoCapture cap("/home/semih/Desktop/OPENCV_ON_LINUX/dizifiles/yenisoncalismalar/kanaldkucukaga.avi");
    if ( !cap.isOpened() )  
    {
        cout << "Cannot open the video file" << endl;
        return -1;
    }

    double fps = cap.get(CV_CAP_PROP_FPS); //get the frames per seconds of the video
    cout << "Frame per seconds : " << fps << endl;
    namedWindow("1",CV_WINDOW_AUTOSIZE);
    namedWindow("2",CV_WINDOW_AUTOSIZE);
    namedWindow("3",CV_WINDOW_AUTOSIZE);
    namedWindow("4",CV_WINDOW_AUTOSIZE);

    namedWindow("5",CV_WINDOW_AUTOSIZE);

    int counter=0;
    int check_counter=0;
    std::string s;

    cv::Rect myROI(699, 474, 10,16);  //location of the countdown Timer
    cv::Mat cropped;
    templ = imread("/home/semih/Desktop/OPENCV_ON_LINUX/dizifiles/yenisoncalismalar/sifir00.png",CV_LOAD_IMAGE_COLOR);
    cv::resize(templ,templ_resized,Size(8,11),CV_INTER_LINEAR);  //8 11

    Mat cropped_bw;
    double minVal; 
    double maxVal; 
    Point minLoc; 
    Point maxLoc;
    Point matchLoc;
    cv::Mat pic;

    while(1)
    {
        bool bSuccess = cap.read(frame);
        if (!bSuccess) 
        {
            cout << "Cannot read the frame from video file" << endl;
            break;
        }
        counter=counter+1;

        cv::Mat croppedRef(frame, myROI);
        cvtColor(croppedRef,cropped_bw,CV_RGB2GRAY);
        cropped_bw = cropped_bw > 200;
        cvtColor(templ_resized,templ_resized_bw,CV_RGB2GRAY);
        templ_resized_bw=templ_resized_bw>200;

        imshow("1",cropped_bw);
        imshow("2",frame);
        imshow("3",templ);
        imshow("4",templ_resized_bw);

        int result_cols =  cropped_bw.cols - templ_resized_bw.cols + 1;
        int result_rows = cropped_bw.rows - templ_resized_bw.rows + 1;

        result.create( result_cols, result_rows, CV_32FC1 );
        matchTemplate( cropped_bw,templ_resized_bw, result, CV_TM_SQDIFF_NORMED);
        normalize( result, result, 0, 1, NORM_MINMAX, -1, Mat() );
        minMaxLoc( result, &minVal, &maxVal, &minLoc, &maxLoc, Mat() );

        matchLoc=minLoc;

        int dogrula;

        if(matchLoc.x>0){
            check_counter=check_counter+1;
        }

        if(check_counter>20){     // if it stays 20 frames, assume "detected
            cout<<"0 number detected"<<endl;
        }

        rectangle(cropped_bw, matchLoc, Point( matchLoc.x + templ_resized_bw.cols , matchLoc.y + templ_resized_bw.rows ), Scalar::all(100), 1, 8, 0 );
        imshow("5",cropped_bw);
        if(waitKey(30) == 27) 
        {
            cout << "esc key is pressed by user" << endl; 
            break; 
        }
    }

    return 0;
}

1 个答案:

答案 0 :(得分:0)

当我试图搜索特定和相同的数字时,我找到了这个解决方案。 这比较两个图像,好像它们是相同的。

#include<opencv2/highgui/highgui.hpp>
#include <iostream>
#include <stdio.h>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <sstream>
using namespace cv;
using namespace std;


    Mat frame;
    Mat img; 
    Mat templ; 
    Mat templ_resized;
    Mat templ_resized_bw;
    Mat result;
    cv::Mat sel;
    cv::Mat img_final;
  //**************
int detect()
    {
VideoCapture cap("/home/semih/Desktop/OPENCV_ON_LINUX/dizifiles/yenisoncalismalar/Final/kucukaga2.avi");
   if ( !cap.isOpened() )  
    {
         cout << "Cannot open the video file" << endl;
         return -1;
    }

double fps = cap.get(CV_CAP_PROP_FPS); //get the frames per seconds of the video
  cout << "Frame per seconds : " << fps << endl;


int counter=0;
int check_counter=0;
    std::string s;

cv::Rect myROI(702, 476, 11,16);   // location of countdown timer



    cv::Mat cropped;
    templ = imread("/home/semih/Desktop/OPENCV_ON_LINUX/dizifiles/yenisoncalismalar/Final/thresh747.png",CV_LOAD_IMAGE_COLOR);
cv::resize(templ,templ_resized,Size(45,45),CV_INTER_LINEAR);  //8 11

    Mat cropped_bw;
    double minVal; 
    double maxVal; 
    Point minLoc; 
    Point maxLoc;
    Point matchLoc;
    cv::Mat pic;

while(1)
        {
        bool bSuccess = cap.read(frame);

         if (!bSuccess) 
        {
                        cout << "Cannot read the frame from video file" << endl;
                       break;
        }
counter=counter+1;


cv::Mat croppedRef(frame, myROI);
cvtColor(croppedRef,cropped_bw,CV_RGB2GRAY);

cv::resize(cropped_bw,cropped_bw,Size(45,45),CV_INTER_LINEAR);

cropped_bw = cropped_bw > 200;

cvtColor(templ_resized,templ_resized_bw,CV_RGB2GRAY);
templ_resized_bw=templ_resized_bw>200;


cv::Mat result2;
Mat croppedsimilar;

Mat templ_resized_re;
Mat templ_cvt;

cvtColor(templ_resized, templ_cvt, CV_BGR2GRAY);



cv::resize(templ_cvt,templ_resized_re,Size(45,45),CV_INTER_LINEAR);
cv::resize(cropped_bw,croppedsimilar,Size(45,45),CV_INTER_LINEAR);

templ_resized_re=templ_resized_re>200;
croppedsimilar=croppedsimilar>200;

imshow("111",croppedsimilar);
imshow("222",templ_resized_re);

int threshold = (double)(templ_resized_re.rows * templ_resized_re.cols) * 0.97; 
// Search for almost same match

cv::compare(croppedsimilar ,  templ_resized_re , result2 , cv::CMP_EQ );


int similarPixels  = countNonZero(result2);

if ( similarPixels  > threshold ) {
   cout << "number '0' found !!!!!" << endl;
}




if(waitKey(30) == 27) 
       {
                cout << "esc key is pressed by user" << endl; 
                break; 
       }

}


return 0;
}