2014-01-09 116 views
2

我试图将bgr mat转换为hsv ma​​t进行一些检测,但hsv图像总是出现块状。这里是我在C++中的代码:在opencv中将bgr转换为hsv时出现块状行为

int main() { 
    const int device = 1; 
    VideoCapture capture(device); 
    Mat input; 
    int key; 
    if(!capture.isOpened()) { 
     printf("No video recording device under device number %i found. Aborting program...\n", device); 
     return -1; 
    } 
    namedWindow("Isolation Test", CV_WINDOW_AUTOSIZE); 
    while(1) { 
     capture >> input; 
     cvtColor(input, input, CV_BGR2HSV); 
     imshow("Isolation Test", input); 
     key = static_cast<int>(waitKey(10)); 
     if(key == 27) 
      break; 
    } 
    destroyWindow("Isolation Test"); 
    return 0; 
} 

Here是输出内容的快照。当我注释掉cvtColor时,输入不显得块状。有什么问题,我该怎么做才能解决它?

+0

在转换之前,图像可能是块状的,但它很难检测到。 JPEG/MPEG压缩正在利用我们的“视觉管道”的不完善性,并因此产生许多难以检测到的伪影。当您用假彩色(例如HSV通道)显示图像时,它们有时变得非常明显。您可以将图像保存为无损格式(png/tiff),并使用颜色检查器调查实际值。 –

+0

我甚至可以在3.0(主)中重现。也与不同的摄像头型号/驱动程序。它只发生在网络摄像头捕获,而不是imread()。不错的谜题;) – berak

+0

@scribblemaniac,你可能想[在这里提出问题](http://code.opencv.org/projects/opencv/issues) – berak

回答

2

我在评论部分提出了一个解释,但决定实际验证我的假设并解释一些关于HSV色彩空间的内容。

代码和OpenCV的cvtColor都没有问题。 RGB图片中存在“块状”工件,但不明显。所有的JPEG家族压缩算法产生这些工件。我们通常看不到它们的原因是这些算法“利用”了我们视觉系统中的弱点并压缩了更多我们不太敏感的东西。

我使用OpenCV s cvtColor`将图像转换回RGB,并且神器消失(图像在下面)。

HSV特别是色彩空间有几个夸大这些工件的特征。其中很重要的一个事实是,无论通道(值/亮度)的哪个位置非常低,通道都非常不稳定并且毫无意义。在极端:[128,255,0] == [0,0,0]

因此,在色彩空间的错误颜色的情况下,图像黑暗区域中非常小且不明显的压缩伪影变得非常突出。

如果您想使用HSV色彩空间作为色彩对比的特征空间,请记住,如果V非常低,H & S是毫无意义的。对于非常低的S值也是如此,这使H值无意义([0,0,100] == [128,0,100])。

顺便说一句。还要记住H通道是循环的,H == 0H == 255之间的差值只是一个灰度级别。

  • 假彩色“块状” HSV图像张贴在使用cvtColor Same image after conversion back to RGB
+0

感谢后续,它已经帮了我很多。我明白你的意思,我想我必须相应地调整我的范围来弥补这一点。 – scribblemaniac

+0

没问题,我可以简单地使用RGB色彩空间(虽然它不是很流行),或者定义HSV中的距离函数,它对低V或S值是强健的。 –

0

我认为这种情况发生,因为imshow函数总是解释图像问题 HSV image posted by @scribblemaniac

  • 图像转换回RGB作为一个简单的RGB或BGR图像。所以你需要在显示图像之前使用cvtColor(input,input,CV_HSV2BGR)将HSV改回BGR。