为什么cvSet2D接受一个双元组,为什么这个元组全部为0保存第一个元素?

时间:2011-09-25 07:09:44

标签: python c image-processing opencv

cvSet2D(matrix, i, j, tuple)

您好。我正在解析http://www.eml.ele.cst.nihon-u.ac.jp/~momma/wiki/wiki.cgi/OpenCV/Gabor%20Filter.html中给出的Gabor过滤器代码。我对cvSet2D有几个问题,特别是在下面的代码片段中使用(如链接中所示):

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元组<given_value_in_double, 0.000000, 0.000000, 0.000000)>。我猜测cvSet2D取前三个值并将其用作RGB 3元组。但是,看到Gabor滤波器的输出或多或少处于灰度级,那将不会成为那样,我的方案中产生的颜色将倾向于红色。那么,cvSet2D对这个元组做了什么?

感谢所有愿意解释的人!

2 个答案:

答案 0 :(得分: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)

因此,标量只需要在其中设置一个通道值。

答案 1 :(得分:1)

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

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

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

由于您正在处理单通道32位浮点图像(CV_32FC1),因此只需继续使用Set2D(image, (value, 0, 0, 0)),一切都应该没问题。