前言
重要的事情说三遍:opencv中的行列和坐标不是对等的!!!
。。。
opencv也用过一段时间了,虽然我没有系统的学习过这个开源包,之前也有些轻视,毕竟也就是一个开源包么,边用边学也不是不行,磕磕绊绊用了一段时间,也没啥问题,知道我想用rectangle函数画图,涉及到坐标时我整个人都开始凌乱了。。。
坐标和行列
初学opencv,你是不是经常用image.at < uchar > (i,j)来访问像素点?具体而言是这样?
for(int i=0;i<image.rows;i++) //行
{
for(int j=0;j<image.cols;j++) //列
{
image.at<uchar>(i,j)=0;
}
}
利用图像的行列确定边界,然后访问像素。我们也知道行列如下图所示:
第0行是黑色块,第0列是蓝色快,简单明了。访问圈圈和叉叉分别如下:
image.at<uchar>(2,2)=0; 即圈圈在第2行第2列
image.at<uchar>(3,5)=0; 即叉叉在第3行第5列
但是千万别把(2,2)和(3,5)看成是圈圈和叉叉的坐标!!!
image.at< uchar >(i,j)中(i,j)仅仅代表第i行第j列,不代表坐标!!!
那坐标是怎么定义的呢?
见上图,将上述方格看成一张图,直角坐标系应该如上图所示。
再回到前面那张图,如果坐标来将的话圈圈的坐标是(2,2)、叉叉的坐标是(5,3)。
给出一段代码,功能是随便点击图片中一点,显示坐标和对应的RGB的像素值。感兴趣的可以去尝试尝试。
#include<opencv2/opencv.hpp>
//#include <opencv2/core/core.hpp>
//#include <opencv2/imgproc/imgproc.hpp>
//#include <opencv2/highgui/highgui.hpp>
#include <opencv2/highgui/highgui_c.h>
using namespace std;
void onMouse(int event, int x, int y, int flags, void* param)
{
cv::Mat* im = reinterpret_cast<cv::Mat*>(param);
switch (event) {
case CV_EVENT_LBUTTONDOWN:
cout << "at(" << x << "," << y << ")pixs value is:(R,G,B)=(" << static_cast<int>
(im->at<cv::Vec3b>(cv::Point(x, y))[2]) <<","<< static_cast<int>
(im->at<cv::Vec3b>(cv::Point(x, y))[1]) <<","<< static_cast<int>
(im->at<cv::Vec3b>(cv::Point(x, y))[0]) <<")"<< endl;
break;
}
}
int main()
{
cv::Mat image = cv::imread("E:\\学习资料\\研一下\\视频图像处理_茅\\homework_NeedHandIn\\火焰检测\\image6.jpg");//读取图片
if (image.empty())
{
cout << "读取图片失败" << endl;
}
cv::namedWindow("原始图像");
cv::setMouseCallback("原始图像", onMouse, reinterpret_cast<void*>(&image));
cv::imshow("原始图像", image);
cv::waitKey(0);
return 0;
}