图像在 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 计算了一个笛卡尔交集:

如果 所有 为真,则结果 (x, y) 为真(uchar 为 255): 对于第一个频道,lower[0] &lt;= img(x, y)[0] &lt;= upper[0]AND 对于第二个频道,lower[1] &lt;= img(x, y)[1] &lt;= upper[1]AND 等等。

换句话说,在它检查了每个通道的像素值与下限和上限之后,逻辑结果然后是“归结”对图像的通道进行逻辑与运算。

“Boiled down”是我对reduction, or fold 的通俗说法,其中一个函数可以接受任意数量的参数,并且可以“缩减”为单个值。求和、乘法、字符串连接等

因此没有必要在cv::inRange 的输出上使用cv::split。事实上,因为输出只有一个通道,调用channels[1]ycrs[1] 将是一种未定义的行为,这将导致调试构建和未定义行为的异常或发布构建的崩溃或内存损坏。

【讨论】:

以上是关于图像在 OPENCV 中具有不同模型的 2 个图像的乘法的主要内容,如果未能解决你的问题,请参考以下文章

以不同方向训练具有相同图像的模型

python opencv笔记

OpenCV每日函数 对象追踪模块 使用增强相关系数 (ECC) 最大化的图像配准

图像分割

如何使函数可以在 OpenCV 中处理不同类型的图像

从一组图像中检测明显不同的图像,例如使用 OpenCV 或 SimpleCV