【问题标题】:Regarding a specific Object Detection in OpenCV using WebCam and comparing it with an input Image关于使用 WebCam 在 OpenCV 中进行特定对象检测并将其与输入图像进行比较
【发布时间】:2014-11-21 09:53:45
【问题描述】:

我是 OpenCV 的新手,想开发一个程序,它接受摄像头输入并将其与对象的已知图像进行比较,该对象将作为 .jpg 图像输入,并且如果网络摄像头的输入与输入图像达到一定的准确度,然后应该显示一些消息等,表明已找到所需的对象。 例如:如果我在网络摄像头之前获得了一条计算机电缆,则需要对其进行检测并与我输入到程序中的计算机电缆的图像进行比较。

我尝试了很多技术,发现模板匹配是有效的,如以下链接中所述--- Real-time template matching - OpenCV, C++

但是,在绘制矩形并获取 roiImage 之后,我想将其与磁盘上的已知图像(在 opencv 工作目录中)进行比较。为此,我尝试将 roiImg 和我的其他图像转换为 HSV 格式,并根据算法获得 4 个值。

我尝试合并这两个代码,但它似乎不起作用,因为 roiImg 是在运行时生成的,并且无法使用 imread 与其他 2 个图像进行比较。

#include <iostream>
#include "opencv2/opencv.hpp"
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/objdetect/objdetect.hpp>

#include <sstream>


using namespace cv;
using namespace std;

Point point1, point2; /* vertical points of the bounding box */
int drag = 0;
Rect rect; /* bounding box */
Mat img, roiImg; /* roiImg - the part of the image in the bounding box */
int select_flag = 0;
bool go_fast = false;

Mat mytemplate;
Mat src_base, hsv_base;
Mat src_test1, hsv_test1;
Mat src_test2, hsv_test2;
Mat hsv_half_down;


///------- template matching -----------------------------------------------------------------------------------------------

Mat TplMatch( Mat &img, Mat &mytemplate )
{
  Mat result;

  matchTemplate( img, mytemplate, result, CV_TM_SQDIFF_NORMED );
  normalize( result, result, 0, 1, NORM_MINMAX, -1, Mat() );

  return result;
}


///------- Localizing the best match with minMaxLoc ------------------------------------------------------------------------

Point minmax( Mat &result )
{
  double minVal, maxVal;
  Point  minLoc, maxLoc, matchLoc;

  minMaxLoc( result, &minVal, &maxVal, &minLoc, &maxLoc, Mat() );
  matchLoc = minLoc;

  return matchLoc;
}


///------- tracking --------------------------------------------------------------------------------------------------------

void track()
{
    if (select_flag)
    {
        //roiImg.copyTo(mytemplate);
//         select_flag = false;
        go_fast = true;
    }

//     imshow( "mytemplate", mytemplate ); waitKey(0);

    Mat result  =  TplMatch( img, mytemplate );
    Point match =  minmax( result ); 

    rectangle( img, match, Point( match.x + mytemplate.cols , match.y + mytemplate.rows ), CV_RGB(255, 255, 255), 0.5 );

    std::cout << "match: " << match << endl;

    /// latest match is the new template
    Rect ROI = cv::Rect( match.x, match.y, mytemplate.cols, mytemplate.rows );
    roiImg = img( ROI );
    roiImg.copyTo(mytemplate);
    imshow( "roiImg", roiImg ); //waitKey(0);

//Compare the roiImg with a know image to calculate resemblence 

/*Method    Base - Base Base - Half Base - Test 1   Base - Test 2

Correlation     1.000000    0.930766    0.182073    0.120447
Chi-square      0.000000    4.940466    21.184536   49.273437
Intersection    24.391548   14.959809   3.889029    5.775088
Bhattacharyya   0.000000    0.222609    0.646576    0.801869

For the Correlation and Intersection methods, the higher the metric, the more accurate the match. As we can see, 
the match base-base is the highest of all as expected. Also we can observe that the match base-half is the second best match (as we predicted). 
For the other two metrics, the less the result, the better the match. We can observe that the matches between the test 1 and test 2 with respect
to the base are worse, which again, was expected.)*/


    src_base = imread("roiImg");
    src_test1 = imread("Samarth.jpg");
    src_test2 = imread("Samarth2.jpg");
    //double l2_norm = cvNorm( src_base, src_test1 );

    /// Convert to HSV
    cvtColor( src_base, hsv_base, COLOR_BGR2HSV );
    cvtColor( src_test1, hsv_test1, COLOR_BGR2HSV );
    cvtColor( src_test2, hsv_test2, COLOR_BGR2HSV );

    hsv_half_down = hsv_base( Range( hsv_base.rows/2, hsv_base.rows - 1 ), Range( 0, hsv_base.cols - 1 ) );

    /// Using 50 bins for hue and 60 for saturation
    int h_bins = 50; int s_bins = 60;
    int histSize[] = { h_bins, s_bins };

    // hue varies from 0 to 179, saturation from 0 to 255
    float h_ranges[] = { 0, 180 };
    float s_ranges[] = { 0, 256 };

    const float* ranges[] = { h_ranges, s_ranges };

    // Use the o-th and 1-st channels
    int channels[] = { 0, 1 };


    /// Histograms
    MatND hist_base;
    MatND hist_half_down;
    MatND hist_test1;
    MatND hist_test2;

    /// Calculate the histograms for the HSV images
    calcHist( &hsv_base, 1, channels, Mat(), hist_base, 2, histSize, ranges, true, false );
    normalize( hist_base, hist_base, 0, 1, NORM_MINMAX, -1, Mat() );

    calcHist( &hsv_half_down, 1, channels, Mat(), hist_half_down, 2, histSize, ranges, true, false );
    normalize( hist_half_down, hist_half_down, 0, 1, NORM_MINMAX, -1, Mat() );

    calcHist( &hsv_test1, 1, channels, Mat(), hist_test1, 2, histSize, ranges, true, false );
    normalize( hist_test1, hist_test1, 0, 1, NORM_MINMAX, -1, Mat() );

    calcHist( &hsv_test2, 1, channels, Mat(), hist_test2, 2, histSize, ranges, true, false );
    normalize( hist_test2, hist_test2, 0, 1, NORM_MINMAX, -1, Mat() );

    /// Apply the histogram comparison methods
    for( int i = 0; i < 4; i++ )
    {
        int compare_method = i;
        double base_base = compareHist( hist_base, hist_base, compare_method );
        double base_half = compareHist( hist_base, hist_half_down, compare_method );
        double base_test1 = compareHist( hist_base, hist_test1, compare_method );
        double base_test2 = compareHist( hist_base, hist_test2, compare_method );

        printf( " Method [%d] Perfect, Base-Half, Base-Test(1), Base-Test(2) : %f, %f, %f, %f \n", i, base_base, base_half , base_test1, base_test2 );
    }


    printf( "Done \n" );

}


///------- MouseCallback function ------------------------------------------------------------------------------------------

void mouseHandler(int event, int x, int y, int flags, void *param)
{
    if (event == CV_EVENT_LBUTTONDOWN && !drag)
    {
        /// left button clicked. ROI selection begins
        point1 = Point(x, y);
        drag = 1;
    }

    if (event == CV_EVENT_MOUSEMOVE && drag)
    {
        /// mouse dragged. ROI being selected
        Mat img1 = img.clone();
        point2 = Point(x, y);
        rectangle(img1, point1, point2, CV_RGB(255, 0, 0), 3, 8, 0);
        imshow("image", img1);
    }

    if (event == CV_EVENT_LBUTTONUP && drag)
    {
        point2 = Point(x, y);
        rect = Rect(point1.x, point1.y, x - point1.x, y - point1.y);
        drag = 0;
        roiImg = img(rect);
        roiImg.copyTo(mytemplate);
//  imshow("MOUSE roiImg", roiImg); waitKey(0);
    }

    if (event == CV_EVENT_LBUTTONUP)
    {
        /// ROI selected
        select_flag = 1;
        drag = 0;
    }

}



///------- Main() ----------------------------------------------------------------------------------------------------------

int main()
{
    int k;

///open webcam
    VideoCapture cap(0);
    if (!cap.isOpened())
      return 1;

 /*   ///open video file
    VideoCapture cap;
    cap.open( "Wildlife.wmv" );
    if ( !cap.isOpened() )
    {   cout << "Unable to open video file" << endl;    return -1;    }*/

    /*    
    /// Set video to 320x240
     cap.set(CV_CAP_PROP_FRAME_WIDTH, 320);
     cap.set(CV_CAP_PROP_FRAME_HEIGHT, 240);*/

    cap >> img;
    GaussianBlur( img, img, Size(7,7), 3.0 );
    imshow( "image", img );

    while (1)
    {
        cap >> img;
        if ( img.empty() )
            break;

    // Flip the frame horizontally and add blur
    cv::flip( img, img, 1 );
    GaussianBlur( img, img, Size(7,7), 3.0 );

        if ( rect.width == 0 && rect.height == 0 )
            cvSetMouseCallback( "image", mouseHandler, NULL );
        else
            track();

        imshow("image", img);
//  waitKey(100);   k = waitKey(75);
    k = waitKey(go_fast ? 30 : 10000);
        if (k == 27)
            break;
    }

    return 0;

}

【问题讨论】:

    标签: opencv visual-c++ face-recognition object-detection haar-classifier


    【解决方案1】:

    如果您想在实时源中检测对象,则在每帧中检测对象效率不高。第一次必须在必须跟踪对象后进行检测。 所以这个过程涉及检测和跟踪.. 为了进行检测,您必须将对象与其他对象进行分割,opencv 提供了许多算法用于根据颜色color based detection从背景中分割对象。除了颜色之外,您可以使用对象的形状从背景中分割对象shape based segmentation

    您可以使用 lk 光流算法作为跟踪的起点。

    此外,您可以使用模板匹配或 camshift 或中间流跟踪器等来获得快速的结果。以上所有算法都将根据对象的比例变化和饲料的照明变化很有用。 opencv 有上述算法的示例程序。

    【讨论】:

    • 谢谢!实际上我打算使用 SURF 算法来检测图像中存在的对象。我的下一个工作是同时输入 2 张图像,然后检测对象以执行特定任务。例如:如果我提供 CPU 背面和计算机电缆的图像,然后将实际的计算机电缆放在网络摄像头前面,程序必须能够将计算机电缆连接到它必须插入的端口在。
    猜你喜欢
    • 2012-12-04
    • 2011-07-21
    • 1970-01-01
    • 1970-01-01
    • 2013-11-30
    • 2010-12-21
    • 1970-01-01
    • 1970-01-01
    • 2021-04-15
    相关资源
    最近更新 更多