一位化学专业的学生向我寻求有关绘制图像分割的帮助: 固定相机在几分钟内每秒拍摄一张实验装置的照片,大约可生成 300 张图像。
设置中的相关部分是从侧面观察到的两层相邻的不同颜色的泡沫,基本上是一个从两侧收缩的双色三明治,除了其中一个泡沫蒸发得更快一些。
我想以能够让我绘制两个泡沫区域的“宽度”随时间变化的方式分割每张图像。
这是一个“图表”:) I want to go from here --> To here
理想情况下,如果有几百个这样的镜头,其中只有宽度发生变化,我就会得到一组可以绘制的标量。 (看起来像 x 轴两侧的谐波级数)
我有一点 python 和 matlab 经验,但从未在 matlab 中使用过 OpenCV 或图像处理工具箱,或者实际上从未处理过任何计算机视觉。你们能不能给我一张路线图,说明要使用哪些包/功能或应该采取的步骤,我将从那里开始?
我不确定如何解决这些问题:
-选择沿切片长度的哪个切片算法测量宽度(即,如果泡沫有点不均匀),尽管这可以忽略。
- 使用哪个库根据颜色分割图像区域(可能是一些 k-means 恶作剧),并有选择地存储生成的分割的空间参数?
-如何在多个文件上迭代上面的内容。
提前致谢!
最佳答案
假设您的强度在转换为灰度后会有所不同(如果不是,只需转换为其他颜色空间,如 HSV 或 LAB,然后使用其中一个组件)
img = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
首先,将您的灰度输入阈值化为几个波段
ret,thresh1 = cv.threshold(img,128,255,cv.THRESH_BINARY)
ret,thresh2 = cv.threshold(img,27,255,cv.THRESH_BINARY_INV)
ret,thresh3 = cv.threshold(img,77,255,cv.THRESH_TRUNC)
ret,thresh4 = cv.threshold(img,97,255,cv.THRESH_TOZERO)
ret,thresh5 = cv.threshold(img,227,255,cv.THRESH_TOZERO_INV)
该值应通过您的实际数据进行测试。这里我只是举个例子
使用半径大于 9 的中值滤波器清理分割后的图像。我预计会有一些噪音。您还可以在此处使用 ROI 来帮助去除部分噪声。但我个人很懒,我只是编写程序来处理所有情况和角度
threshholed_images_aftersmoothing = cv2.medianBlur(threshholed_images,9)
每个波段将对应一种颜色(图层)。现在你应该从一个来源获得 N 个分割图像。其中 N 是您希望跟踪的层数
其次 使用 opencv 函数 bounding rect 找到每个层的位置和宽度/高度,也就是每个 threshholed_images_aftersmoothing。例如。每个子分割图像上的 boundingrect。
C++: Rect boundingRect(InputArray points)
Python: cv2.boundingRect(points) → retval¶
最后,矩形有 x,y, height 和 width 属性。可以使用简单的排序顺序,根据rect属性x从上到下层排序。运行所有 vieo 以获得 x(layer id)、高度与时间图。
Rect API
Public Attributes
_Tp **height** // this is what you are looking for
_Tp width
_Tp **x** // this tells you the position of the band
_Tp y
通过绘制随时间变化的相应高度(|AB| 或 |CD|),您可以获得所需的图表。
更正确的方法是使用卡尔曼滤波器来跟踪位置和高度图,因为我预计会出现某种气泡并且会干扰层的高度。
老实说,我没想到化学专业的学生会擅长这个。哈哈祝你好运
如果我不看 stackoverflow,你可以在这里找到我或者发邮件给我
关于python - 在包含数百张图像的数据集中比较和绘制相同颜色的区域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56414175/