0

我正在尝试将视频中的 HSV 帧传递给函数,但函数似乎对它没有任何作用。我究竟做错了什么?该函数应该遍历每个像素,并根据其色调范围使其变为黑色或白色,给我留下一个二值图像。相反,它似乎根本不会影响 HSV 图像......

感谢 PS 抱歉代码格式错误,StackOverflow 不允许我发布原始格式。

void sort (IplImage *skinmask)
{
  for (int row=0; row<=skinmask->height;row++)
  {
    uchar* pixelrow=(uchar*)(skinmask->imageData+(row*(skinmask->widthStep)));
    for (int column=0; column<=skinmask->width; column++)
    {
        if (6<pixelrow[3*column]<36)
        {
            pixelrow[3*column]=256;
            pixelrow[(3*column)+1]=256;
            pixelrow[(3*column)+2]=256;
        }
        else
        {
            pixelrow[3*column]=0;
            pixelrow[(3*column)+1]=0;
            pixelrow[(3*column)+2]=0;
        }
        column++;
    }
    row++;
  }
  cvMorphologyEx(skinmask,skinmask,NULL,NULL,CV_MOP_CLOSE,1);
}
4

1 回答 1

3

在 OpenCV 中进行逐个像素阈值处理通常是错误的方法 - 有些函数适用于更简单的整个图像阵列,并且已经针对速度进行了优化。

在这种情况下,首先尝试分割图像以分离出 H/S/V 通道,然后在色调通道上设置阈值以获得蒙版(您可能必须使用两个蒙版的交集,您可以使用乘法或“按位和") - 生成的蒙版是您的黑白图像。

(我意识到我已经链接到 C++ 文档,但我相信您可以在旧式 OpenCV 文档中找到等效函数)

更新

好的,我会尝试编写一些代码来说明我的意思。我还找到了我正在寻找的函数,它比 Threshold 更好,它是InRangeS。这使您可以一次在所有通道上设置上限和下限,并为您将它们全部应用到您的蒙版中。

void HSVImageToMask(IplImage * image, cvMat * mask)
/* mask should be the same size as image, and of type CV_8UC1            */
/* e.g. cvMat * mask = cvCreateMat(image->width, image->height, CV8UC1); */
{
  double hMin = 6;
  double hMax = 36;
  double sMin = 10;  /* not sure what value you need */
  double sMax = 245; /* not sure what value you need */
  double vMin = 0;
  double vMax = 255;

  CvScalar hsvMin = cvScalar(hMin, sMin, vMin);
  CvScalar hsvMax = cvScalar(hMax, sMax, vMax);

  cvInRangeS(image, hsvMin, hsvMax, mask);
}

PS。我发现了您原始代码的问题 - 您应该使用 255 而不是 256 作为您的“白色”值。这种方法还是更好的:)

聚苯乙烯。毕竟我们不需要它们,但供将来参考:

“按位和”

cvAnd(const CvArr* src1, const CvArr* src2, CvArr* dst)

如果您有两个黑白蒙版,这将为您提供交叉点。使用 cvOr 获得联合。

于 2011-09-21T02:18:04.287 回答