CamshiftDemo(1)

 
前些天学习的一些东西。主要是利用opencv中camshiftdemo算法实现物体的颜色的追踪和识别。这是前面一部分,主要包括对目标物体颜色的截取和对截取图像进行相关的文件处理。
这次学习的最大收获是在opencv中进行coding时,最好避免C接口和C++接口函数的混用;虽然最后编译会通过,但是在运行exe时就会出现异常。
详见http://stackoverflow.com/questions/13686606/can-opencv-be-developed-using-c-and-c-together#comment18806065_13686606
实现代码和注释如下。
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
//Task2_Part1 :关于颜色的识别和追踪
//该部分主要实现对目标物体颜色的截取和对截取图像进行相关的文件处理(Hue通道信息保存)
//--By Steven Meng  2012.12.07
 
//算法实现:主要通过鼠标相应函数(OnMouse)选区目标物体区域
//          对分离截取图像(BGR—>HSV->Hue)
//          遍历Hue通道图像
 
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/video/tracking.hpp"
#include <iostream>
#include <fstream>                     //文件流处理
#include <ctype.h>
 
using namespace std;
using namespace cv;
 
//截取矩形的对角线点pt1和pt2
Point pt1=Point(0,0);
Point pt2=Point(0,0);
bool is_selecting=false;
 
//鼠标相应函数
static void onMouse(int mouseEvent,int x,int y,int flags,void* param)
{
    switch(mouseEvent)
    {
    case CV_EVENT_LBUTTONDOWN:      //左键按下
        pt1 = Point(x,y);
        pt2 = Point(x,y);
        is_selecting = true;
        break;
    case CV_EVENT_MOUSEMOVE:        //鼠标移动 
        if(is_selecting)
            pt2 = Point(x,y);
        break;
    case CV_EVENT_LBUTTONUP:       //左键发开
        pt2 = Point(x,y);
        is_selecting = false;
        break;
    }
}
 
//主函数部分
int main()
{
    //理论上应该先用相机拍下目标物体,然后进行下述步骤
    //因设备缘故 省略
 
    //*****************--1:实现截图***********************
    cout<<"Start Chosing Object Color (Cutting by hand)"<<endl;
 
    Mat img=imread("E:\\我的图片\\View\\101891fa1c5c7f5aa9d3112e.jpg");
    Mat saveImage;                       //存放截取后的图片
    Mat img_show=img.clone();
    bool isFinished=true;                //flag
 
    namedWindow("Task2",1);
    setMouseCallback("Task2",onMouse);   //鼠标相应函数部分
 
    while(isFinished)
    {
        img.copyTo(img_show);
        rectangle(img_show,pt1,pt2,Scalar(255,255,255),2);   //画截取框
        cv::imshow("Task2",img_show);
 
        //当敲下回车时,图片保存并退出循环
        char key=waitKey(10);
        if (key=='\r')
        {
            saveImage=img(Rect(pt1.x,pt1.y,std::abs(pt2.x-pt1.x),std::abs(pt2.y-pt1.y)));
            imwrite("save.jpg",saveImage);   //保存截图
            imshow("showSaveImage",saveImage);
            isFinished=false;
        }
         
    }
    cout<<"Chosing Object Color finished."<<endl;
 
    //*****************--2:对截图(saveImage)进行处理:SHV***********************
    Mat hsv;
    cvtColor(saveImage,hsv,CV_BGR2HSV);
    vector<cv::Mat> v_channel;
    split(hsv,v_channel);
    imshow("HueImage",v_channel[0]); //--得到Hue通道的图
    if (v_channel[0].data==0)
    {
        cout<<"Error getting the Hue Channel"<<endl;
    }
 
    //--文件处理
    ofstream myfile;
    myfile.open("hueData.txt");     //hueData.txt用于保存Hue通道信息
    myfile<<"Following is the Hue image pixel value"<<endl;
    cout<<"Following is the Hue image pixel value"<<endl;
 
    for (int i=0;i<3;i++)           //为节约时间只选取hue中3*3的pixel
    {
        for (int j=0;j<3;j++)
        {
            cout<<(int)v_channel[0].at<uchar>(i,j)<<endl;    //注意1:强转换为int,不然结果是字母而不是数字
                                                             //    2:hue为单通道
            myfile<<(int)v_channel[0].at<uchar>(i,j)<<endl;  //保存Hue通道信息到hueData.txt文件
        }
    }
    cout<<"Inputing Hue pixel value Finished Task2_Part1 is over."<<endl;
    cout<<"Task2_Part1 is over."<<endl;
 
 
    //*****************--3:利用截图(saveImage)进行模版匹配***********************(失败。)
    //cv::VideoCapture  cap;
    /*Mat objectImage,result;
    //cap.open(-1);
    //if (cap.isOpened()==0)
    //{
        //cout<<"******Error Opening the Viedo"<<endl;
        //return -1;
    //}
    //for (;;)
    //{
        objectImage=imread("E:\\我的图片\\View\\renren_1345473239607.png");
        if (objectImage.empty())
        {
            cout<<"Fail to capture the object"<<endl;
            //break;
        }
 
        int result_cols=objectImage.cols-saveImage.cols+1;
        int result_rows=objectImage.rows-saveImage.rows+1;
        result.create(result_cols,result_rows,CV_32FC1);
 
        //--开始进行模版匹配和结果归一化
        matchTemplate(objectImage,saveImage,result,CV_TM_SQDIFF);
        normalize(result,result,0,1,NORM_MINMAX,-1,Mat());
 
        //定位最佳的匹配位置
        double minValue,maxValue;
        Point minLoc,maxLoc,matchLoc;
        minMaxLoc(result,&minValue,&maxValue,&minLoc,&maxLoc,Mat());
        matchLoc=minLoc;
 
        //显示匹配结果
         rectangle( objectImage, matchLoc, Point( matchLoc.x + saveImage.cols , matchLoc.y + saveImage.rows ), Scalar::all(0), 2, 8, 0 );
         imshow("match result",objectImage);
        // wait()
 
 
    //}*/
 
    waitKey(0);
    return 0;
}
 
    
Steven Meng
2012.12.11
posted @ 2012-12-11 18:39  StevenMeng  阅读(517)  评论(0编辑  收藏  举报