在包含数百张图像的数据集中比较和绘制相同颜色的区域
Comparing and plotting regions of the same color over a dataset of a few hundred images
一位化学专业的学生向我求助绘制图像分割:
固定相机在几分钟内每秒拍摄一次实验装置的照片,因此大约可生成 300 张图像。
设置中的相关部分是从侧面观察到的两层相邻的不同颜色的泡沫,一个从两侧收缩的双色三明治,基本上,除了其中一个泡沫蒸发得更快。
我想分割每张图像,这样我就可以根据时间绘制两个泡沫区域的 "width"。
这是一个"diagram" :)
I want to go from here --> To here
理想情况下,给定几百个这样的镜头,其中只有宽度发生变化,我得到一组可以绘制的标量。 (看起来像 x 轴两侧的谐波级数)
我有一些 python 和 matlab 经验,但从未在 matlab 中使用过 OpenCV 或图像处理工具箱,或者实际上从未处理过任何计算机视觉。你们能给我一张路线图,说明 packages/functions 使用什么或应该采取的步骤吗?
我不确定如何解决这些问题:
-选择沿着切片长度的哪个切片算法测量宽度(即如果泡沫有点不均匀),虽然这可以忽略。
-使用哪个库根据颜色分割图像区域(可能是一些 k-means 恶作剧),并有选择地存储生成的分割的空间参数?
-如何在多个文件上迭代上面的内容。
提前致谢!
您可以 select 感兴趣的区域直接位于泡沫中间,几个像素宽。如果您为每个图像堆叠这些区域,它会随着时间的推移显示缩小。
例如,如果您为 roi 使用 3 像素宽度,则 300 张图像的结果将是 900 像素宽的图像,其中左侧是实验的开始,右侧是结束。下图可以帮助你理解:
虽然我还没有完全测试过,但这段代码应该可以工作。请注意,您引用的文件夹中必须只有图像。
import cv2
import numpy as np
import os
# path to folder that holds the images
path = '.'
# dimensions of roi
x = 0
y = 0
w = 3
h = 100
# store references to all images
all_images = os.listdir(path)
# sort images
all_images.sort()
# create empty result array
result = np.empty([h,0,3],dtype=np.uint8)
for image in all_images:
# load image
img = cv2.imread(path+'/'+image)
# get the region of interest
roi = img[y:y+h,x:x+w]
# add the roi to previous results
result = np.hstack((result,roi))
# optinal: save result as image
# cv2.imwrite('result.png',result)
# display result - can also plot with matplotlib
cv2.imshow('Result', result)
cv2.waitKey(0)
cv2.destroyAllWindows()
问题编辑后更新:
如果泡沫有不同的颜色,您可以通过转换您的 hsv 图像并使用 inrange
轻松地将它们按颜色分开。这将创建一个掩码(= 具有 0-255 值的二维数组,每个像素一个),您可以使用它来计算平均高度并提取图像的参数和区域。
您可以找到一个脚本来帮助您找到用于在此 GitHub
上进行分离的 HSV 颜色
假设您的强度在转换为灰度后会有所不同(如果不是,只需转换为其他颜色 space,如 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 找到每个层 AKA 的位置和 width/height 每个 threshholed_images_aftersmoothing .例如。每个 sub-segmented 图像上的边界矩形。
C++: Rect boundingRect(InputArray points)
Python: cv2.boundingRect(points) → retval¶
Last,矩形有 x,y,高度和宽度 属性。可以使用简单的排序顺序,根据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|)随时间的变化,您可以获得您需要的图表。
更正确的方法是使用卡尔曼滤波器来跟踪位置和高度图,因为我预计会出现某种气泡并且会干扰层的高度。
老实说,我没想到化学专业的学生会擅长这个。哈哈祝你好运
有任何问题你可以在这里找到我或者如果我不看 Whosebug 就发邮件给我
一位化学专业的学生向我求助绘制图像分割: 固定相机在几分钟内每秒拍摄一次实验装置的照片,因此大约可生成 300 张图像。
设置中的相关部分是从侧面观察到的两层相邻的不同颜色的泡沫,一个从两侧收缩的双色三明治,基本上,除了其中一个泡沫蒸发得更快。
我想分割每张图像,这样我就可以根据时间绘制两个泡沫区域的 "width"。
这是一个"diagram" :) I want to go from here --> To here
理想情况下,给定几百个这样的镜头,其中只有宽度发生变化,我得到一组可以绘制的标量。 (看起来像 x 轴两侧的谐波级数)
我有一些 python 和 matlab 经验,但从未在 matlab 中使用过 OpenCV 或图像处理工具箱,或者实际上从未处理过任何计算机视觉。你们能给我一张路线图,说明 packages/functions 使用什么或应该采取的步骤吗?
我不确定如何解决这些问题:
-选择沿着切片长度的哪个切片算法测量宽度(即如果泡沫有点不均匀),虽然这可以忽略。
-使用哪个库根据颜色分割图像区域(可能是一些 k-means 恶作剧),并有选择地存储生成的分割的空间参数?
-如何在多个文件上迭代上面的内容。
提前致谢!
您可以 select 感兴趣的区域直接位于泡沫中间,几个像素宽。如果您为每个图像堆叠这些区域,它会随着时间的推移显示缩小。
例如,如果您为 roi 使用 3 像素宽度,则 300 张图像的结果将是 900 像素宽的图像,其中左侧是实验的开始,右侧是结束。下图可以帮助你理解:
虽然我还没有完全测试过,但这段代码应该可以工作。请注意,您引用的文件夹中必须只有图像。
import cv2
import numpy as np
import os
# path to folder that holds the images
path = '.'
# dimensions of roi
x = 0
y = 0
w = 3
h = 100
# store references to all images
all_images = os.listdir(path)
# sort images
all_images.sort()
# create empty result array
result = np.empty([h,0,3],dtype=np.uint8)
for image in all_images:
# load image
img = cv2.imread(path+'/'+image)
# get the region of interest
roi = img[y:y+h,x:x+w]
# add the roi to previous results
result = np.hstack((result,roi))
# optinal: save result as image
# cv2.imwrite('result.png',result)
# display result - can also plot with matplotlib
cv2.imshow('Result', result)
cv2.waitKey(0)
cv2.destroyAllWindows()
问题编辑后更新:
如果泡沫有不同的颜色,您可以通过转换您的 hsv 图像并使用 inrange
您可以找到一个脚本来帮助您找到用于在此 GitHub
上进行分离的 HSV 颜色假设您的强度在转换为灰度后会有所不同(如果不是,只需转换为其他颜色 space,如 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 找到每个层 AKA 的位置和 width/height 每个 threshholed_images_aftersmoothing .例如。每个 sub-segmented 图像上的边界矩形。
C++: Rect boundingRect(InputArray points)
Python: cv2.boundingRect(points) → retval¶
Last,矩形有 x,y,高度和宽度 属性。可以使用简单的排序顺序,根据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|)随时间的变化,您可以获得您需要的图表。
更正确的方法是使用卡尔曼滤波器来跟踪位置和高度图,因为我预计会出现某种气泡并且会干扰层的高度。
老实说,我没想到化学专业的学生会擅长这个。哈哈祝你好运
有任何问题你可以在这里找到我或者如果我不看 Whosebug 就发邮件给我