您的位置:首页 > 运维架构

用鼠标框选图片感兴趣区域并提取灰度直方图

2014-03-05 16:09 211 查看

         用鼠标框选图片感兴趣区域并提取灰度直方图

                                           Jun.L
                   http://blog.csdn.net/jingjun1822


    最近看了很多提取边缘局部特征的文章,包括Hog,Snake等等,会在这段时间内分享我的阅读心得。CV刚刚接触不久,基础薄弱,见识短浅。简直是要理论没理论,要代码没代码。不过既然在做了就不能急躁,应该静下心来,扎扎实实地走好每一步。因为是初学者,理论分析不到位或者代码有误的地方,前辈们看到了还望不吝赐教,在此先谢过了。
    为了做一些局部特征的分析,我把以前所编的用鼠标提取图片感兴趣区域并提取灰度直方图的opencv程序拿了出来,打算把它改造成提取一些局部特征的工具。程序运行环境opencv2.4.3+VS2010。参考资料OpenCV2 Computer
Vision Application Programmming Cookbook是一本学习opencv2.0系列的C++接口的好书。
下载链接:http://download.csdn.net/detail/a973206267/6996239
main.cpp    

//Use mouse to get gray histogram form RIO
//Author:Jun.L
//Data:2013-12-10
//Homepage:
//Email:junsfield@163.com
//references:OpenCV2 Computer Vision Application Programmming Cookbook

#include "stdafx.h"
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
#include "Ms_program.h"
#include <iostream>

using namespace std;
using namespace cv;
CvRect ROI_rect;
IplImage* workImg=NULL;
IplImage* Imgshow=NULL;
bool check_line_state=false;
void on_mouse4(int event, int x,int y,int flags, void* param);

int _tmain(int argc, _TCHAR* argv[])
{
workImg=cvLoadImage("E:\\dataset\\input\\pics\\head977.jpg",-1);
if(!workImg){
cout<<"Open File Error!"<<endl;
return -1;
}
Imgshow=cvCreateImage(cvSize(workImg->width,workImg->height),workImg->depth,workImg->nChannels);
cvCopy(workImg,Imgshow);
cvNamedWindow("image",1);
cvShowImage( "image",workImg);
cvSetMouseCallback("image",on_mouse4);
//cv::Mat Matinput(MP1.Imginput,false);
cvWaitKey(0);
cvReleaseImage(&Imgshow);
cvReleaseImage(&workImg);

}
void on_mouse4(int event, int x,int y,int flags, void* param){
int thickness=2;
CvPoint p1,p2;
if(event==CV_EVENT_LBUTTONDOWN){    //left button of mouse is down
ROI_rect.x=x;
ROI_rect.y=y;
check_line_state=true;
}
else if(check_line_state&&event==CV_EVENT_MOUSEMOVE){
Imgshow = cvCreateImage(cvGetSize(workImg), IPL_DEPTH_8U, 3);//use Imgshow to show that we draw a green rect in it
Imgshow  = cvCloneImage(workImg);
p1=cvPoint(ROI_rect.x,ROI_rect.y);
p2=cvPoint(x,y);
cvRectangle(Imgshow,p1,p2,CV_RGB(0,255,150),thickness,CV_AA,0);
cvShowImage("image",Imgshow);
cvReleaseImage(& Imgshow);
}
else if(check_line_state&&event==CV_EVENT_LBUTTONUP){   //left button of mouse is up
ROI_rect.width = abs(x - ROI_rect.x);
ROI_rect.height = abs(y - ROI_rect.y);
cvSetImageROI(workImg, ROI_rect);
IplImage* RoiImg;
IplImage* Imggray;
Imggray = cvCreateImage(cvSize(ROI_rect.width,ROI_rect.height),8,1);
RoiImg = cvCreateImage(cvSize(ROI_rect.width,ROI_rect.height),8,3);
cvCopy(workImg,RoiImg);
cvResetImageROI(workImg);
cvNamedWindow("ROI",1);
cvShowImage("ROI",RoiImg);
/***********************draw the gray histogram*************************/
cvCvtColor(RoiImg,Imggray,CV_RGB2GRAY);
Mos_pro MP1;
cvNamedWindow("histogram",1);
cv::imshow("histogram",MP1.getHistogramImage(Imggray));
cv::MatND histo=MP1.getHistogram(Imggray);
for(int i=0;i<256;i++)
cout<<"value"<<i<<"="<<histo.at<float>(i)<<endl;
cvReleaseImage(&RoiImg);
cvReleaseImage(&Imggray);
check_line_state=false;
cvWaitKey(20);
}
}

Ms_program.h    

#if !defined MS_PROGRAM
#define MS_PROGRAM
#include "stdafx.h"
#define  WINSIZE 3
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
#include <math.h>
#include <iostream>
using namespace std;
using namespace cv;

class Mos_pro
{
public:
Mos_pro();
cv::MatND getHistogram(const cv::Mat &image){
cv::MatND hist;
// Compute histogram
cv::calcHist(&image,
1,			// histogram of 1 image only
channels,	// the channel used
cv::Mat(),	// no mask is used
hist,		// the resulting histogram
1,			// it is a 1D histogram
histSize,	// number of bins
ranges		// pixel value range
);
return hist;
}
cv::Mat getHistogramImage(const cv::Mat &image){

// Compute histogram first
cv::MatND hist= getHistogram(image);
// Get min and max bin values
double maxVal=0;
double minVal=0;
cv::minMaxLoc(hist, &minVal, &maxVal, 0, 0);
// Image on which to display histogram
cv::Mat histImg(histSize[0], histSize[0], CV_8U,cv::Scalar(255));
// set highest point at 90% of nbins
int hpt = static_cast<int>(0.9*histSize[0]);
// Draw vertical line for each bin
for( int h = 0; h < histSize[0]; h++ ) {
float binVal = hist.at<float>(h);
int intensity = static_cast<int>(binVal*hpt/maxVal);
cv::line(histImg,cv::Point(h,histSize[0]),cv::Point(h,histSize[0]-intensity),cv::Scalar::all(0));
}
return histImg;
}
private:
int histSize[1];
float hranges[2];
const float* ranges[1];
int channels[1];
};
#endif

Ms_program.cpp

#include "stdafx.h"
#include "Ms_program.h"
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
#include <math.h>
#include <iostream>

using namespace std;
using namespace cv;

Mos_pro::Mos_pro(){
// Prepare arguments for 1D histogram
histSize[0]= 256;
hranges[0]= 0.0;
hranges[1]= 255.0;
ranges[0]= hranges;
channels[0]= 0; // by default, we look at channel 0
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息