OpenCV - 奇数 HSV 范围检测
OpenCV - odd HSV range detection
我有一个 Qt 应用程序,我必须在其中找到点击坐标周围几个像素的 HSV 范围,以便稍后进行跟踪。我是这样做的:
cv::Mat temp;
cv::cvtColor(frame, temp, CV_BGR2HSV); //frame is pulled from a video or jpeg
cv::Vec3b hsv=temp.at<cv::Vec3b>(frameX,frameY); //sometimes SIGSEGV?
qDebug() << hsv.val[0]; //look up H
qDebug() << hsv.val[1]; //look up S
qDebug() << hsv.val[2]; //look up V
//just base values so far, will work on range later
emit hsvDownloaded(hsv.val[0], hsv.val[0]+5, hsv.val[1], 255, hsv.val[2], 255); //send to GUI which automaticly updates worker thread
现在,情况很奇怪。这些是结果(红色圆圈表示点击位置):
红色很奇怪,形状的上半部分被正确检测到,下半部分没有,尽管它是相同颜色的固体。
并进行实际测试
它检测到 HSV {95,196,248}
坦率地说这是荒谬的(基值太高了)。 None 检测到的像素甚至不是被点击的像素。 100% 时间检测到该球的最佳值是 H:35-141 S:0-238 V:65-255
。我想从归一化直方图中获得 HSV 范围,但我什至无法获得正确的基值。这是怎么回事?当 OpenCV 使用 kalibrowanyPlik.read(frame);
拉帧时,默认配色方案是 BGR,对吗?
为什么颜色检测如此随机?
正如 berak 所提到的,您的代码看起来您使用索引以错误的顺序访问像素。
这意味着您的像素位置是错误的,除了位于对角线上的像素外,因此将正确检测到对角线周围的点击对象,而所有其他对象则不会。
为了避免一再混淆,我希望您了解为什么 OpenCV 对索引使用 (row,col) 排序:
OpenCV 使用矩阵来表示图像。在数学中,二维矩阵使用 (row,col) 索引,查看 http://en.wikipedia.org/wiki/Index_notation#Two-dimensional_arrays 并观察索引。所以对于矩阵,通常先使用行索引,然后使用列索引。
不幸的是,图像和像素通常具有 (x,y) 索引,对应于数学图形和坐标系中的 x/y axis/direction。所以这里先用x位置,再用y位置。
幸运的是,OpenCV 提供了两种不同版本的 .at
方法,一种用于访问像素位置,另一种用于访问矩阵元素(最终是完全相同的元素)。
matrix.at<type>(row,column) // matrix indexing to access elements
// which equals
matrix.at<type>(y,x)
和
matrix.at<type>(cv::Point(x,y)) // pixel/position indexing to access elements
由于第一个版本的效率应该稍微高一些,如果位置尚未作为 cv::Point 对象给出,则应该首选它。所以最好的方法通常是记住,openCV 使用矩阵来表示图像,它使用矩阵索引符号来访问元素。
顺便说一句,我看到人们想知道为什么 matrix.at<type>(cv::Point(y,x))
在了解到 openCV 图像使用 "wrong ordering" 后无法按预期方式工作。希望我解释完后不要再提这个问题
顺便说一句:在学校我已经想知道,为什么矩阵首先索引行,而函数图首先索引 x 轴。我发现不对两者都使用 "same" 排序是愚蠢的,但我仍然不得不忍受它:D(最后,两者与另一个没有太大关系)
我有一个 Qt 应用程序,我必须在其中找到点击坐标周围几个像素的 HSV 范围,以便稍后进行跟踪。我是这样做的:
cv::Mat temp;
cv::cvtColor(frame, temp, CV_BGR2HSV); //frame is pulled from a video or jpeg
cv::Vec3b hsv=temp.at<cv::Vec3b>(frameX,frameY); //sometimes SIGSEGV?
qDebug() << hsv.val[0]; //look up H
qDebug() << hsv.val[1]; //look up S
qDebug() << hsv.val[2]; //look up V
//just base values so far, will work on range later
emit hsvDownloaded(hsv.val[0], hsv.val[0]+5, hsv.val[1], 255, hsv.val[2], 255); //send to GUI which automaticly updates worker thread
现在,情况很奇怪。这些是结果(红色圆圈表示点击位置):
红色很奇怪,形状的上半部分被正确检测到,下半部分没有,尽管它是相同颜色的固体。
并进行实际测试
它检测到 HSV {95,196,248}
坦率地说这是荒谬的(基值太高了)。 None 检测到的像素甚至不是被点击的像素。 100% 时间检测到该球的最佳值是 H:35-141 S:0-238 V:65-255
。我想从归一化直方图中获得 HSV 范围,但我什至无法获得正确的基值。这是怎么回事?当 OpenCV 使用 kalibrowanyPlik.read(frame);
拉帧时,默认配色方案是 BGR,对吗?
为什么颜色检测如此随机?
正如 berak 所提到的,您的代码看起来您使用索引以错误的顺序访问像素。
这意味着您的像素位置是错误的,除了位于对角线上的像素外,因此将正确检测到对角线周围的点击对象,而所有其他对象则不会。
为了避免一再混淆,我希望您了解为什么 OpenCV 对索引使用 (row,col) 排序:
OpenCV 使用矩阵来表示图像。在数学中,二维矩阵使用 (row,col) 索引,查看 http://en.wikipedia.org/wiki/Index_notation#Two-dimensional_arrays 并观察索引。所以对于矩阵,通常先使用行索引,然后使用列索引。
不幸的是,图像和像素通常具有 (x,y) 索引,对应于数学图形和坐标系中的 x/y axis/direction。所以这里先用x位置,再用y位置。
幸运的是,OpenCV 提供了两种不同版本的 .at
方法,一种用于访问像素位置,另一种用于访问矩阵元素(最终是完全相同的元素)。
matrix.at<type>(row,column) // matrix indexing to access elements
// which equals
matrix.at<type>(y,x)
和
matrix.at<type>(cv::Point(x,y)) // pixel/position indexing to access elements
由于第一个版本的效率应该稍微高一些,如果位置尚未作为 cv::Point 对象给出,则应该首选它。所以最好的方法通常是记住,openCV 使用矩阵来表示图像,它使用矩阵索引符号来访问元素。
顺便说一句,我看到人们想知道为什么 matrix.at<type>(cv::Point(y,x))
在了解到 openCV 图像使用 "wrong ordering" 后无法按预期方式工作。希望我解释完后不要再提这个问题
顺便说一句:在学校我已经想知道,为什么矩阵首先索引行,而函数图首先索引 x 轴。我发现不对两者都使用 "same" 排序是愚蠢的,但我仍然不得不忍受它:D(最后,两者与另一个没有太大关系)