版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_25254777/article/details/80184225
#include <opencv2/opencv.hpp>
#include<string>
#include <iostream>
using namespace cv;
using namespace std;
RNG g_rng(12345);//毛大大的博客里看到的生成随机数,用于生成随机颜色
Point lt_point = Point(-1, -1);
Point tr_point = Point(-1, -1);
Mat roi;
void on_mouse(int event, int x, int y, int flags, void *ustc)
//event鼠标事件代号,x,y鼠标坐标,flags拖拽和键盘操作的代号
{
Mat& image = *(cv::Mat*) ustc;//这样就可以传递Mat信息了,很机智
if (event == CV_EVENT_LBUTTONDOWN)//左键按下,读取初始坐标,并在图像上该点处划圆
{
lt_point = Point(x, y);
}
else if (event == CV_EVENT_MOUSEMOVE && !(flags & CV_EVENT_FLAG_LBUTTON))
{
}
else if (event == CV_EVENT_MOUSEMOVE && (flags & CV_EVENT_FLAG_LBUTTON))//左键按下时,鼠标移动,则在图像上划矩形
{
tr_point = Point(x, y);
}
else if (event == CV_EVENT_LBUTTONUP)//左键松开,将在图像上划矩形
{
cout << "you zai shubiao yidong limian " << endl;
tr_point = Point(x, y);
roi = image(Rect(lt_point, tr_point));
imwrite("roi.jpg", roi);
}
}
int main()
{
//system("color 9F");//毛大大程序里的,改变console颜色
Mat org, temp1, temp2;
VideoCapture cp(2);
namedWindow("img");//定义一个img窗口
setMouseCallback("img", on_mouse, (void*)&temp2);//调用回调函数
//在setMouseCallback中传递最好不要用org原图。
vector<Mat> channels;
while (waitKey(30) != 27) {
cp >> org;
org.copyTo(temp1);//用来显示点的坐标以及临时的方框
temp2 = org.clone();
rectangle(temp1, lt_point, tr_point, cv::Scalar(g_rng.uniform(0, 255), g_rng.uniform(0, 255), g_rng.uniform(0, 255)));//随机颜色
//putText(temp1, "(" + std::to_string(鼠标位置.x) + "," + std::to_string(鼠标位置.y) + ")", 鼠标位置, FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 0, 0, 255));
if (roi.empty())
{
cout << "kong" << endl;
}
else
{
split(roi, channels);//分离色彩通道(rgb)
int histSize = 100;
/// 设定取值范围 ( R,G,B) )
float range[] = { 0, 255 };
const float* histRange = { range };
bool uniform = true; bool accumulate = false;
Mat r_hist, g_hist, b_hist;
Mat meger(1, 300, CV_32FC1);
/// 计算直方图:
calcHist(&channels[0], 1, 0, Mat(), r_hist, 1, &histSize, &histRange, uniform, accumulate);
calcHist(&channels[1], 1, 0, Mat(), g_hist, 1, &histSize, &histRange, uniform, accumulate);
calcHist(&channels[2], 1, 0, Mat(), b_hist, 1, &histSize, &histRange, uniform, accumulate);
//r_hist 输出的一维直方图 histSize直方图分几个区间,直方图要收集的数据范围(如果大于0~255,则不在收集范围内)
// 创建直方图画布
int hist_w = 400; int hist_h = 400;
int bin_w = cvRound((double)hist_w / histSize);
Mat histImage(hist_w, hist_h, CV_8UC3, Scalar(0, 0, 0));
//下面注释的一点代码是自己写的,可以不用加。
/// 将直方图归一化到范围 [ 0, histImage.rows ]
/*normalize(r_hist, r_hist, 0, 1.0, NORM_MINMAX, -1, Mat());
normalize(g_hist, g_hist, 0, 1.0, NORM_MINMAX, -1, Mat());
normalize(b_hist, b_hist, 0, 1.0, NORM_MINMAX, -1, Mat());*/
/*for (int i = 0; i < histSize; i++)
{
meger.at<float>(i) = r_hist.at<float>(i);
meger.at<float>(i+100) = g_hist.at<float>(i);
meger.at<float>(i + 200) = b_hist.at<float>(i);
}*/
//cout << "meger : " << meger << endl;
/// 在直方图画布上画出直方图
for (int i = 1; i < histSize; i++)
{
line(histImage, Point(bin_w*(i - 1), hist_h - cvRound(r_hist.at<float>(i - 1))),
Point(bin_w*(i), hist_h - cvRound(r_hist.at<float>(i))),
Scalar(0, 0, 255), 2, 8, 0);
line(histImage, Point(bin_w*(i - 1), hist_h - cvRound(g_hist.at<float>(i - 1))),
Point(bin_w*(i), hist_h - cvRound(g_hist.at<float>(i))),
Scalar(0, 255, 0), 2, 8, 0);
line(histImage, Point(bin_w*(i - 1), hist_h - cvRound(b_hist.at<float>(i - 1))),
Point(bin_w*(i), hist_h - cvRound(b_hist.at<float>(i))),
Scalar(255, 0, 0), 2, 8, 0);
}
/// 显示直方图
namedWindow("calcHist Demo", CV_WINDOW_AUTOSIZE);
imshow("calcHist Demo", histImage);
imshow("roi", roi);
}
imshow("img", temp1);
}
return 0;
}