图像在 OPENCV 中具有不同模型的 2 个图像的乘法
Posted
技术标签:
【中文标题】图像在 OPENCV 中具有不同模型的 2 个图像的乘法【英文标题】:Multiplication of 2 images where the images have different models in OPEN CV 【发布时间】:2014-09-27 20:02:18 【问题描述】:我正在尝试将两个不同模型的图像相乘,在我的例子中是 HSV 和 YCRCB。 我每次都得到“向量超出范围错误”。 我检查了被相乘的输入图像的大小、行数和列数。我知道该值超过 255。 我试图实现这个方法opencv - image multiplication,但是代码对许多必须初始化的 MAT 有一定的影响。这也让我问一个问题,是否可以将超过 1 个通道的图像相乘。还尝试了直接乘法,但它不起作用,所以尝试明智地乘法通道。为了使事情变得更容易,我使用了循环方法,但随后发生了错误。
关于代码及其原因的简短摘要:我将其用于皮肤检测,但希望进一步降低噪音。我认为这可以通过将阈值操作(对于 HSV 和 YCRCB)生成的 2 个输出图像相乘来完成。由于这些图像在图像中具有不同的噪声,因此乘法的输出将具有更少的噪声(我在不同的屏幕上看到了输出,重叠区域非常小)因此这几乎可以随时检测肤色并且噪声会最小化,因此将有助于更好地跟踪皮肤。
下面给出的代码不完整,因为它永远不会执行到最后。在此之后,进行形态和膨胀操作,就是这样。 这是我第一次在 Stack Overflow 上提问,我还在学习 Open CV 。抱歉,如果我的描述过度,欢迎提出所有建议。谢谢。
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv\cv.h>
#include <opencv\highgui.h>
#include <iostream>
#include <opencv2\imgproc\imgproc.hpp>
using namespace cv;
using namespace std;
char key;
Mat image,hsv,ycr;
vector<Mat> channels,ycrs,threshold_output;
int main()
VideoCapture cap(0); // open the default camera
if(!cap.isOpened()) // check if we succeeded
cout << "Cannot open the web cam" << endl;
return -1;
while(1)
cap>>image;
cvtColor( image, ycr, CV_BGR2YCrCb ); //Converts into YCRCB
cvtColor( image, hsv, CV_BGR2HSV ); //Converts into HSV
Mat imgThresholded;
Mat imgThresholded1;
inRange(ycr, Scalar(0, 140,105 ), Scalar(255, 165,135), imgThresholded1); //for yrcrcb range
inRange(hsv, Scalar(0, 48,150 ), Scalar(20, 150,255), imgThresholded); //for hsv range
split(imgThresholded1, channels);
split(imgThresholded, ycrs);
for( int i = 0; i <3 ; i++ )
multiply(channels[i],ycrs[i], threshold_output[i], 1,-1 );
//code breaks here
【问题讨论】:
【参考方案1】:即使inRange
的输入是多通道的,inRange
的输出也将是单通道CV_8UC1
。
原因是inRange
计算了一个笛卡尔交集:
lower[0] <= img(x, y)[0] <= upper[0]
,AND
对于第二个频道,lower[1] <= img(x, y)[1] <= upper[1]
,AND
等等。
换句话说,在它检查了每个通道的像素值与下限和上限之后,逻辑结果然后是“归结”对图像的通道进行逻辑与运算。
“Boiled down”是我对reduction, or fold 的通俗说法,其中一个函数可以接受任意数量的参数,并且可以“缩减”为单个值。求和、乘法、字符串连接等
因此没有必要在cv::inRange
的输出上使用cv::split
。事实上,因为输出只有一个通道,调用channels[1]
或ycrs[1]
将是一种未定义的行为,这将导致调试构建和未定义行为的异常或发布构建的崩溃或内存损坏。
【讨论】:
以上是关于图像在 OPENCV 中具有不同模型的 2 个图像的乘法的主要内容,如果未能解决你的问题,请参考以下文章