2011-09-25 63 views
1

cvSet2D(matrix, i, j, tuple)为什么cvSet2D接受一个双元组元组,为什么这个元组全部为0,除了第一个元素?

嗨。我正在解剖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)) 

正如我” m知道cvSet2D将矩阵的第(j,i)个像素设置为最后一个参数中定义的元组的等效颜色值。但是为什么它需要一个双元组?将一个像素颜色定义为一个整数元组,是不是更自然一些?

最后,如果我正确读取了文档,则使用的cvScalar方法将返回4元组<given_value_in_double, 0.000000, 0.000000, 0.000000)>。我推测cvSet2D取前三个值并将其用作RGB三元组。但是,看到Gabor滤波器的输出或多或少处于灰度级,这不会成为这种情况,我的方案中生成的颜色将倾向于红色。那么,cvSet2D对这个元组做了什么?

谢谢任何​​会花费心思解释的人!

回答

1

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

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

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

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

+0

感谢你们俩。但额外感谢@misha的额外细节。 – skytreader

1

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

EDIT:在代码示例你联系,kernel具有类型CV_32FC1这意味着它只有一个信道。所以呢kernelImg

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

所以它是有道理的标量只需要中设置一个信道值。

相关问题