还是和以往一样,在研究OpenCV。
在看到OpenCV.2.Computer.Vision.Application.Programming.Cookbook的第五章的时候出现了个watershed算法,用起来到挺简单,但是一直想不通那个marker image应该怎么标!
书上有一句:
Here, we will mark foreground pixels with label 255 and background pixels with label 128 (this choice is totally arbitrary, any label number other than 255 would work).
他说这个选择是任意的!
然后继续看:
在看到OpenCV.2.Computer.Vision.Application.Programming.Cookbook的第五章的时候出现了个watershed算法,用起来到挺简单,但是一直想不通那个marker image应该怎么标!
书上有一句:
Here, we will mark foreground pixels with label 255 and background pixels with label 128 (this choice is totally arbitrary, any label number other than 255 would work).
他说这个选择是任意的!
然后继续看:
1 2 3 4 5 | // Identify image pixels without objects cv::Mat bg; cv::dilate(binary,bg,cv::Mat(),cv::Point(-1,-1),6); cv::threshold(bg,bg,1,128,cv::THRESH_BINARY_INV); //这里我就怪了!前面说Marker是任意的,这里的阈值结果为啥要反一反啊? |
于是我就试着把cv::THRESH_BINARY_INV改为cv::THRESH_BINARY
看看会出现什么情况!结果查找结果跟前景图一样了!!
看看会出现什么情况!结果查找结果跟前景图一样了!!
后来我干脆直接讲前景图作为marker,结果全是白色!!
后来书上又看到一句:
Users can input a marker image with any number of labels with pixels of unknown labeling left to value 0
很是难理解!
于是就开始网上搜索资料!
还真被找到了!
以下是相关参考介绍:
函数cvWatershed实现在[Meyer92]描述的变量分水岭,基于非参数标记的分割算法中的一种。在把图像传给函数之前,用户需要用正指标大致勾画出图像标记的感兴趣区域。比如,每一个区域都表示成一个或者多个像素值1,2,3的互联部分。这些部分将作为将来图像区域的种子。标记中所有的其他像素,他们和勾画出的区域关系不明并且应由算法定义,应当被置0。这个函数的输出则是标记区域所有像素被置为某个种子部分的值,或者在区域边界则置-1。
注:每两个相邻区域也不是必须有一个分水岭边界(-1像素)分开,例如在初始标记图像里有这样相切的部分。opencv例程文件夹里面有函数的视觉效果演示和用户例程。见watershed.cpp。
看了这个,才有点理解了。那老外应该说的value 0应该是指不确定关系的区域应该将像素设为0,也就是黑色区域。
这样也就理解了为什么直接cv::THRESH_BINARY为啥得不到好看的样子。因为原来的marker 白色部分(前景、主体)和 灰色(背景)是连在一起的而且白色被灰色包围。黑色的地方应该不是那种书上叫做label的地方!所以从白色和灰色地带开始 “注水” 当他们都 “碰” 到一起就停止了,所以最后白色也就没有任何变化。
而且我还发现,直接cv::THRESH_BINARY 得到的图像存在segment 但是没有 watershed 说明并不是两个不同的标记所形成的边界会产生分水岭!!貌似得经过一段未知区域(黑色部分)
这里是别人对watershed的理解:
http://blog.csdn.net/fdl19881/article/details/6749976
以上是我的个人理解,如有错误还请指正!!
后来书上又看到一句:
Users can input a marker image with any number of labels with pixels of unknown labeling left to value 0
很是难理解!
于是就开始网上搜索资料!
还真被找到了!
以下是相关参考介绍:
函数cvWatershed实现在[Meyer92]描述的变量分水岭,基于非参数标记的分割算法中的一种。在把图像传给函数之前,用户需要用正指标大致勾画出图像标记的感兴趣区域。比如,每一个区域都表示成一个或者多个像素值1,2,3的互联部分。这些部分将作为将来图像区域的种子。标记中所有的其他像素,他们和勾画出的区域关系不明并且应由算法定义,应当被置0。这个函数的输出则是标记区域所有像素被置为某个种子部分的值,或者在区域边界则置-1。
注:每两个相邻区域也不是必须有一个分水岭边界(-1像素)分开,例如在初始标记图像里有这样相切的部分。opencv例程文件夹里面有函数的视觉效果演示和用户例程。见watershed.cpp。
看了这个,才有点理解了。那老外应该说的value 0应该是指不确定关系的区域应该将像素设为0,也就是黑色区域。
这样也就理解了为什么直接cv::THRESH_BINARY为啥得不到好看的样子。因为原来的marker 白色部分(前景、主体)和 灰色(背景)是连在一起的而且白色被灰色包围。黑色的地方应该不是那种书上叫做label的地方!所以从白色和灰色地带开始 “注水” 当他们都 “碰” 到一起就停止了,所以最后白色也就没有任何变化。
而且我还发现,直接cv::THRESH_BINARY 得到的图像存在segment 但是没有 watershed 说明并不是两个不同的标记所形成的边界会产生分水岭!!貌似得经过一段未知区域(黑色部分)
这里是别人对watershed的理解:
http://blog.csdn.net/fdl19881/article/details/6749976
以上是我的个人理解,如有错误还请指正!!