第一天我主要是完成了opencv的一个安装,并设置了好了它的属性便于之后使用。我之后也是找了一些资料,网上大部分都是用python,但是我还是想从c++学起,之后再来看看是否需要学习python.我的学习主要基于在知乎上看到的一位up主来进行我接下来的学习:
通过鼠标点击操作获取图像的像素坐标和像素值
1.创建鼠标操作函数的头文件
我按照给的程序编程,会发现有些地方理解不了程序,我将这些地方梳理一下:
1.1reinterpret_cast运算符允许将任意指针转换到其他指针类型,也允许做任意整数类型和任意指针类型之间的转换,可以参考下面的文章:
关于C++中的reinterpret_cast_Kcnco216的博客-CSDN博客_c++ reinterpret_cast
1.2 static_cast比较接近于C语言中的强制转换,多用于不同的基本数据类型的转换:
C++: static_cast_风静如云的博客-CSDN博客_c++ static_cast
1.3函数中指针的用法
C++指针详解_小鱼的编程之路的博客-CSDN博客_c++指针
1.4访问图像像素
以8位(0~255)灰度图像和BGR彩色图像为例,用at可以访问图像(j,i)处像素
//灰度图像
image.at<uchar>(j,i)//j为行数,i为列数
//BGR彩色图像
image.at<Vec3b>(j,i)[0] //B分量
image.at<Vec3b>(j,i)[1] //G分量
image.at<Vec3b>(j,i)[2] //R分量
1.5关于Mat数据类型需要了解,我找了一个文档,感觉还行:
在梳理完之后,整个头文件的编写就会比较轻松:
#pragma once
#include "iostream"
#include "opencv2/opencv.hpp"
using namespace cv;
using namespace std;
void onMouse(int event, int x, int y, int flags, char*param);
void onMouse(int event, int x, int y, int flags, char*param)
{
Mat*im = reinterpret_cast<Mat*>(param);
int channels = static_cast<int>(im->channels());
int point = static_cast<int>(im->at<uchar>(Point(x,y)));
switch(event)
{
case EVENT_LBUTTONDOWN:
if(channels == 1)
//若图像为单通道图像,则显示鼠标点击的坐标和灰度值
switch(im->type())
{
case 0:
cout<<"at("<<x<<","<<y<<") value is: "<<
static_cast<int>(im->at<uchar>(Point(x,y))) << endl ;break;
case 1:
cout<<"at("<<x<<","<<y<<") value is: "<<
static_cast<int>(im->at<char>(Point(x,y))) << endl ;break;
case 2:
cout<<"at("<<x<<","<<y<<") value is: "<<
static_cast<int>(im->at<ushort>(Point(x,y))) << endl ;break;
case 3:
cout<<"at("<<x<<","<<y<<") value is: "<<
static_cast<int>(im->at<short>(Point(x,y))) << endl ;break;
case 4:
cout<<"at("<<x<<","<<y<<") value is: "<<
static_cast<int>(im->at<int>(Point(x,y))) << endl ;break;
case 5:
cout<<"at("<<x<<","<<y<<") value is: "<<
static_cast<int>(im->at<float>(Point(x,y))) << endl ;break;
case 6:
cout<<"at("<<x<<","<<y<<") value is: "<<
static_cast<int>(im->at<double>(Point(x,y))) << endl ;break;
}
break;
else
//若图像为彩色图像,则点击鼠标显示坐标以及对应的B,G,R值
cout<<"at("<<x<<","<<y<<")"
<<"B value is:"<<static_cast<int>(im->at<Vec3b>(Point(x,y))[0])<<" "
<<"G value is:"<<static_cast<int>(im->at<Vec3b>(Point(x,y))[1])<<" "
<<"R value is:"<<static_cast<int>(im->at<Vec3b>(Point(x,y))[2])<<" "
<<endl;
break;
}
}
2.编写主程序
用到了一个函数setMouseCallback,就是通过setMouseCallback函数来设置鼠标事件的回调函数,从而使得每次操作鼠标之后就会调用对应的回调函数,可参考下面博客:
Opencv之鼠标响应setMouseCallback()的用法_五仁月饼哭了的博客-CSDN博客_setmousecallback
主程序如下图:
#include "onMouse.h"
#include "iostream"
#include "opencv2/opencv.hpp"
using namespace cv;
using namespace std;
int main()
{
Mat image = imread("D://Backup//Documents//My Pictures//1.jpg");//读取文件夹中的图像
imshow("image",image);
setMouseCallback("image",onMouse,reinterpret_cast<void*>(&image));//关联显示图像和onMouse函数,将image从“cv::Mat”转换为“void *”
waitKey(0);
return 0;
}
结果如下图所示:
今天就先到这里了,感觉有好多要学的呀~加油!~~~