【问题标题】:Why does cvSet2D take in a tuple of doubles, and why is this tuple all 0 save for the first element?为什么 cvSet2D 接受一个双精度元组,为什么这个元组除了第一个元素之外都是 0?
【发布时间】:2011-11-24 12:58:42
【问题描述】:

cvSet2D(matrix, i, j, tuple)

嗨。我正在剖析 http://www.eml.ele.cst.nihon-u.ac.jp/~momma/wiki/wiki.cgi/OpenCV/Gabor%20Filter.html 中给出的 Gabor 过滤器代码。我对 cvSet2D 有几个问题,尤其是在以下代码 sn-ps 中使用的问题(如链接中给出的):

C 代码:

for (x = -kernel_size/2;x<=kernel_size/2; x++) {
  for (y = -kernel_size/2;y<=kernel_size/2; y++) {
    kernel_val = exp( -((x*x)+(y*y))/(2*var))*cos( w*x*cos(phase)+w*y*sin(phase)+psi);
    cvSet2D(kernel,y+kernel_size/2,x+kernel_size/2,cvScalar(kernel_val));
    cvSet2D(kernelimg,y+kernel_size/2,x+kernel_size/2,cvScalar(kernel_val/2+0.5));
  }
}

Python 代码:

for x in range(-kernel_size/2+1,kernel_size/2+1):
      for y in range(-kernel_size/2+1,kernel_size/2+1):
          kernel_val = math.exp( -((x*x)+(y*y))/(2*var))*math.cos( w*x*math.cos(phase)+w*y*math.sin(phase)+psi)
          cvSet2D(kernel,y+kernel_size/2,x+kernel_size/2,cvScalar(kernel_val))
          cvSet2D(kernelimg,y+kernel_size/2,x+kernel_size/2,cvScalar(kernel_val/2+0.5))

据我所知,cvSet2D 将矩阵的第 (j, i) 个像素设置为最后一个参数中定义的元组的等效颜色值。但是为什么它需要一个双精度元组呢?看到一个像素颜色被定义为一个整数元组,接收一个整数元组不是更自然吗?

最后,如果我正确阅读了文档,使用的 cvScalar 方法会返回 4 元组 &lt;given_value_in_double, 0.000000, 0.000000, 0.000000)&gt;。我推测 cvSet2D 采用前三个值并将其用作 RGB 3 元组。但是,看到 Gabor 过滤器的输出或多或少是灰度的,这并不成立,我的方案中产生的颜色将倾向于红色。那么,cvSet2D 对这个元组做了什么?

感谢任何愿意花时间解释的人!

【问题讨论】:

    标签: python c image-processing opencv


    【解决方案1】:

    我认为对于灰度图像(矩阵),CvSet2D 使用 cvScalar 中的第一个值设置唯一的通道(亮度)。 CvSet2D 的文档好像坏了,我会尝试在代码中验证。

    编辑:在您链接到的代码示例中,kernel 的类型为 CV_32FC1,这意味着它只有一个通道。 kernelImg也是如此:

    kernel = cvCreateMat(kernel_size,kernel_size,CV_32FC1)
    kernelimg = cvCreateImage(cvSize(kernel_size,kernel_size),IPL_DEPTH_32F,1)
    

    因此,标量只需要在其中设置一个通道值是有意义的。

    【讨论】:

      【解决方案2】:

      在 OpenCV 中,图像可以有 1 个(灰度)、2、3 个(RGB)或 4 个(RGB 加 alpha)通道。一个Set2D 函数用于所有图像,无论它们有多少通道。该元组的每个元素都用于指定通道值。

      你总是通过元组传递四个值,但 OpenCV 只会使用其中的第一个 N,其中 N 是图像中的通道数。它将忽略其余部分。零只是一个可接受的占位符,表示“此值无关紧要”。当然,你可以传入任何你想要的值,但是你的代码的可读性会受到影响。

      double 用作参数类型的原因可能是因为它是 Python 中可以使用的最高精度类型。 OpenCV 会将此值转换为正确的底层类型(它从图像中获取)。

      由于您正在处理单通道 32 位浮点图像 (CV_32FC1),因此请继续使用 Set2D(image, (value, 0, 0, 0)),一切都会好起来的。

      【讨论】:

      • 感谢你们俩。但要特别感谢 @misha 提供的更多详细信息。
      猜你喜欢
      • 1970-01-01
      • 2023-02-24
      • 2022-01-17
      • 1970-01-01
      • 2021-12-07
      • 2015-10-08
      • 1970-01-01
      • 2018-10-07
      • 1970-01-01
      相关资源
      最近更新 更多