博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
基础学习笔记之opencv(23):OpenCV坐标体系的初步认识
阅读量:6977 次
发布时间:2019-06-27

本文共 2368 字,大约阅读时间需要 7 分钟。

 

  前言

  相信很多朋友在使用OpenCV的时候会遇到一个小问题,且有时候对这样的小问题没有引起足够的重视,或者通过表面想当然的去编程,所以调试代码时出现一些莫名其妙的问题,最后发现问题时时间已经过去了一大把。最近我在调试一个项目时就遇到过这种情况,即Mat::at(x,y)和Mat::at(Point(x, y))的区别,我在项目中把这2种看成效果一样的,结果这个问题调试时纠结了2天(因为该工程有关OpenCV的代码有上千行,且没有怀疑这两者的区别,因此有时候出现一些莫名其妙的结果,花了很多时间才找问题所在)。其实关于Mat的at访问时这2者的区别我以前也做过笔记,只是此时不小心忘记了。这次专门为这个写篇小笔记,提醒下自己。

  开发环境:OpenCV2.4.3+QtCreator2.5.1

 

  实验基础

  本次实验通过一个简短的例子,主要来说明下面4个问题:

  1. 坐标体系中的零点坐标为图片的左上角,X轴为图像矩形的上面那条水平线;Y轴为图像矩形左边的那条垂直线。该坐标体系在诸如结构体Mat,Rect,Point中都是适用的。(虽然网上有学着说OpenCV中有些数据结构的坐标原点是在图片的左下角,但是我暂时还没碰到过)。

  2. 在使用image.at<TP>(x1, x2)来访问图像中点的值的时候,x1并不是图片中对应点的x轴坐标,而是图片中对应点的y坐标。因此其访问的结果其实是访问image图像中的Point(x2, x1)点,即与image.at<TP>(Point(x2, x1))效果相同。

  3. 如果所画图像是多通道的,比如说image图像的通道数时n,则使用Mat::at(x, y)时,其x的范围依旧是0到image的height,而y的取值范围则是0到image的width乘以n,因为这个时候是有n个通道,所以每个像素需要占有n列。但是如果在同样的情况下,使用Mat::at(point)来访问的话,则这时候可以不用考虑通道的个数,因为你要赋值给获取Mat::at(point)的值时,都不是一个数字,而是一个对应的n维向量。

  4. 多通道图像在使用minMaxLoc()函数是不能给出其最大最小值坐标的,因为每个像素点其实有多个坐标,所以是不会给出的。因此在编程时,这2个位置应该给NULL。

 

  实验代码及注释

  main.cpp:

#include 
#include
#include
using namespace std;using namespace cv;int main(){ Mat image, image_3c; image.create(Size(256, 256), CV_8UC1); image_3c.create(Size(256, 256), CV_8UC3); //3通道的图像 image.setTo(0); image_3c.setTo(0); image.at
(10, 200) = 255; //使用at函数的地方,用的是10,200 Point point(20, 100); image.at
(point) = 250;//使用at函数的地方,用的是Point(10,200) image_3c.at
(10, 300) = 255; image_3c.at
(10, 302) = 254; Point point_3c(20, 200); image_3c.at
(point_3c) = 250; double maxVal = 0; //最大值一定要赋初值,否则运行时会报错 Point maxLoc; minMaxLoc(image, NULL, &maxVal, NULL, &maxLoc); cout << "单通道图像最大值: " << maxVal << endl; double min_3c, max_3c; //注意多通道在使用minMaxLoc()函数是不能给出其最大最小值坐标的,因为每个像素点其实有多个坐标,所以是不会给出的 minMaxLoc(image_3c, &min_3c, &max_3c, NULL, NULL); cout << "3通道图像最大值: " << max_3c << endl; imshow("image", image); imshow("image_3c", image_3c); waitKey(0); return 0;}

 

  实验结果:

  单通道图像的输出结果如下所示:

  

  由上图可以看出,黑色的图像中有2个白色的点(读者可以仔细看下,由于只有1个像素点,所以需要自己找下,呵呵)的位置是不同的,因此可以证明Mat::at(x,y)和Mat::at(Point(x, y))是有区别的。

 

  3通道图像的输出结果如下所示:

  

  由上图可以看出,3通道的图像也是有2个点的,但是程序中在使用Mat::at(x, y)其y的值为300和302,这已经超出了图像的宽度256。这同时证明了实验基础中的第3点。

 

  后台输出结果如下:

  

 

  实验总结:由此可见,平时一定要注意一些细节上的东西。

 

 

 

转载于:https://www.cnblogs.com/tornadomeet/archive/2012/12/12/2813939.html

你可能感兴趣的文章
要哭了,模拟器键盘一直不显示
查看>>
获取下个月的今天
查看>>
elasticsearch简介
查看>>
文件分区格式化及挂载
查看>>
Centos运行级别和开机过程
查看>>
Linux 装B之作酷炫小工具
查看>>
Citrix Avalon安装实验手册之一----Avalon概述及实验环境准备
查看>>
动态表单构建器——建造者模式
查看>>
Android 自动化测试
查看>>
MySQL 5.5 服务器变量详解(二)
查看>>
bootstrap table
查看>>
CentOS 7 yum 安装 MySQL5.7
查看>>
企业网络翻译官——DNS
查看>>
RocketMQ3.2.2生产者发送消息自动创建Topic队列数无法超过4个
查看>>
USG防火墙telnet实验
查看>>
[给12306支招]取消车票预订-采用全额预售(充值)
查看>>
linux下使profile和.bash_profile立即生效的方法
查看>>
Operations Manager 2012 SP1配置部署系列之(二) SCOM监控SCVMM
查看>>
父域与子域之的信任关系
查看>>
Android中后台定时任务实现,即时数据同步问题思考!
查看>>