Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在图像中找到区域最大值/最小值?_Python_Opencv_Scipy_Scikit Image - Fatal编程技术网

Python 如何在图像中找到区域最大值/最小值?

Python 如何在图像中找到区域最大值/最小值?,python,opencv,scipy,scikit-image,Python,Opencv,Scipy,Scikit Image,我试图在这张图片中找到区域最大值: 要在其位置像这样切割: 我找到了一种过滤区域最大值的方法,但我无法使其适用于我的案例 到目前为止,我的代码是: import numpy as np import cv2 import skimage as sm from skimage.morphology import reconstruction import scipy as sp img = cv2.imread('img.png', 0) img = sm.img_as_float(img)

我试图在这张图片中找到区域最大值:

要在其位置像这样切割:

我找到了一种过滤区域最大值的方法,但我无法使其适用于我的案例

到目前为止,我的代码是:

import numpy as np
import cv2
import skimage as sm
from skimage.morphology import reconstruction
import scipy as sp

img = cv2.imread('img.png', 0)

img = sm.img_as_float(img)
img = sp.ndimage.gaussian_filter(img, 1)

seed = np.copy(img)
seed[1:-1,1:-1] = img.min()
mask = img
dilated = reconstruction(seed, mask, method = 'dilation')
img = img - dilated

cv2.imshow('img', img)
cv2.waitKey()
我的解决方案:

两者都会导致:

看到一种不局限于水平像素的方法会很有趣

在过滤区域最大值后,您可以尝试使用操作分离这两个片段。根据区域最小厚度,使用较大的内核或多个打开调用

要找到洞口的准确切割位置,可以执行几个后续的洞口操作调用,直到单个水滴拆分为两个。通过分析cv::detectContours得到的轮廓,可以检测到该位置

你也会发现这是有用的。其结果是从每个点到最近边界的距离。其思想是进行图像骨架化,并沿骨架线取距离变换结果的最小值,以找到切割位置

此外,您还可以尝试基于白色像素位置的k=2的k均值聚类。切割线将位于簇之间

编辑: 你们可能会发现这很有用,因为大家都在讨论类似的问题。其中一个答案使用cv::凸面缺陷来查找分离点。

在过滤区域最大值后,您可以尝试使用操作来分离这两个片段。根据区域最小厚度,使用较大的内核或多个打开调用

要找到洞口的准确切割位置,可以执行几个后续的洞口操作调用,直到单个水滴拆分为两个。通过分析cv::detectContours得到的轮廓,可以检测到该位置

你也会发现这是有用的。其结果是从每个点到最近边界的距离。其思想是进行图像骨架化,并沿骨架线取距离变换结果的最小值,以找到切割位置

此外,您还可以尝试基于白色像素位置的k=2的k均值聚类。切割线将位于簇之间

编辑:
你们可能会发现这很有用,因为大家都在讨论类似的问题。其中一个答案使用cv::凸面缺陷来找到分离点。

如果你的染色单体我将以这种方式引用显示的结构,因为它看起来像一个都是以这种方式对齐的,你可以简单地计算每行的白色像素,并搜索最小值

请看一下下面的代码,希望它是不言自明的:

进口cv2 将numpy作为np导入 加载输入图像 输入=cv2.imread'images/Q6YM9.png',cv2.imread\u灰度 提取染色单体结构看起来像一个。。。 _,染色单体=cv2.thresholdinput,250255,cv2.Threshold_二进制 按行像素值求和 rowPixelSum=np.sumChromoid/255,轴=1 检测包含非零元素的所有行 ind=np.whererowPixelSum>0[0] 排除染色单体顶部和底部的n行 警告:检查合理性指数是否超出范围等。 nEx=15 ind=ind[15:lenind-nEx] 检测具有最小像素计数的行的索引 cutRow=ind[np.argminrowPixelSum[ind]] 以最小像素计数检测行上染色单体的开始和结束 row=np。其中染色单体[cutRow,:]>0[0] xStart=行[0] xEnd=行[-1] 用于可视化:通过行以最小像素数绘制黑线 cv2.lineinput,xStart,cutRow,xEnd,cutRow,0,3 cv2.LineChromoid,xStart,cutRow,xEnd,cutRow,0,3 写入输出图像 cv2.imwrite'images\input.png',输入 cv2.imwrite'images\chromoid.png',chromoid 输出如下所示:

如果你的染色单体有不同的方向,可以根据染色单体的主成分在上述代码之前进行一些旋转


希望有帮助

如果你的染色单体我将以这种方式引用显示的结构,因为它看起来像是一个以这种方式排列的结构,那么你可以简单地计算每行的白色像素数,并搜索最小值

请看一下下面的代码,希望它是不言自明的:

进口cv2 将numpy作为np导入 加载输入图像 输入=cv2.imread'images/Q6YM9.png',cv2.imread\u灰度 提取染色单体结构看起来像一个。。。 _,染色单体=cv2.thresholdinput,250255,cv2.Threshold_二进制 按行像素值求和 rowPixelSum=np.sumChromoid/255,轴=1 检测包含非零元素的所有行 ind=np.whererowPixelSum>0[0] 排除染色单体顶部和底部的n行 警告:检查合理性指数是否超出范围等。 nEx=15 ind=ind[15:lenind-nEx] 检测具有最小像素计数的行的索引 cutRow=ind[np.argminrowPixelSum[ind]] 以最小像素计数检测行上染色单体的开始和结束 row=np。其中染色单体[cutRow,:]>0[0] xStart=行[0] xEnd=行[-1] 用于可视化:通过行以最小像素数绘制黑线 cv2.lineinput、xStart、cutRow、xEnd ,cutRow,0,3 cv2.LineChromoid,xStart,cutRow,xEnd,cutRow,0,3 写入输出图像 cv2.imwrite'images\input.png',输入 cv2.imwrite'images\chromoid.png',chromoid 输出如下所示:

如果你的染色单体有不同的方向,可以根据染色单体的主成分在上述代码之前进行一些旋转


希望有帮助

什么不起作用?找到进行拆分的位置。提供结果表示,请提供图像。我没有结果,因为我不知道如何找到相关点。什么不起作用?找到进行拆分的位置。提供结果表示,请提供图像。我没有结果,因为我不知道如何找到相关点。是的,但我首先如何找到区域最小值?是的,但我首先如何找到区域最小值?谢谢你的回答。这种方法在我的案例中有效。只有一件事需要解决。现在,切割可能不仅发生在物体的中间,也发生在极端的顶部或底部,因为水平长度在那里是最小的。知道如何解决这个问题吗?@ArturMüllerRomanov请看看我编辑的解决方案。我通过排除染色单体顶部和底部一定数量的行,用每行最少的白色像素替换了该部分。那本来是个更好的主意。谢谢你的回答。这种方法在我的案例中有效。只有一件事需要解决。现在,切割可能不仅发生在物体的中间,也发生在极端的顶部或底部,因为水平长度在那里是最小的。知道如何解决这个问题吗?@ArturMüllerRomanov请看看我编辑的解决方案。我通过排除染色单体顶部和底部一定数量的行,用每行最少的白色像素替换了该部分。那本来是个更好的主意。
import numpy as np
import cv2

img = cv2.imread('img.png', 0)

_, thresh = cv2.threshold(img, 250, 255, cv2.THRESH_BINARY)

rows = np.sum(thresh/255, axis = 1)
ol = len(np.nonzero(rows)[0])
L = []
z = 0
for idx, row in enumerate(rows):
    if row > 0:
        if z > 5 and z < ol - 5:
            L.append(idx)
        z += 1
split = np.min(rows[L])
thresh[np.where(rows == split)[0][0]] = 0

cv2.imshow('img', thresh)
cv2.waitKey()
import numpy as np
import cv2

img = cv2.imread('img.png', 0)

_, thresh = cv2.threshold(img, 250, 255, cv2.THRESH_BINARY)

rows = np.sum(thresh/255, axis = 1)
exclude = 5
idx = np.where(rows > 0)[0]
idx = idx[exclude : len(idx) - exclude]
cut = idx[np.argmin(rows[idx])]
thresh[cut] = 0

cv2.imshow('img', thresh)
cv2.waitKey()