Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/302.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_Object Detection - Fatal编程技术网

Python 图像分析、对象形状、中心和极值

Python 图像分析、对象形状、中心和极值,python,opencv,object-detection,Python,Opencv,Object Detection,我编写了一个程序,从灰度图像中建立一个阈值,并找到它的下部对象的中心。这还用于在对象中绘制几何体(线)cv2.PCACompute()函数用于查找对象的中心。完成后,我可以画线来匹配对象的近似形状并进行进一步分析 因此: 我需要找到的是物体的极值,而不是中心。但是为了计算它们,我需要画一条从中心开始的线。问题是,我需要告诉程序对象的大小。现在,我正试图通过检测物体的极值而不是中心来实现自动化。我想知道你是否能帮我 输入图像: 首先,创建一个阈值,并从中移除上部对象: import cv2 im

我编写了一个程序,从灰度图像中建立一个阈值,并找到它的下部对象的中心。这还用于在对象中绘制几何体(线)
cv2.PCACompute()
函数用于查找对象的中心。完成后,我可以画线来匹配对象的近似形状并进行进一步分析

因此:

我需要找到的是物体的极值,而不是中心。但是为了计算它们,我需要画一条从中心开始的线。问题是,我需要告诉程序对象的
大小。现在,我正试图通过检测物体的极值而不是中心来实现自动化。我想知道你是否能帮我

输入图像:

首先,创建一个阈值,并从中移除上部对象:

import cv2
import numpy as np

#required to draw the length of the lins, originating from the core of object
scale = 20              #factor by which original image was scaled up
shard_size = 12*scale   #length of object

#import image
img = cv2.imread('img.png', 0)

#build threshold
_, thresh = cv2.threshold(img,
                           235,
                           255,
                           cv2.THRESH_BINARY)

#remove upper object from image
z = 0
for x in thresh[::-1]:
    v = 0
    for el in x:
        if el > 0:
            break
        v += 1
    z += 1
    if el > 0:
        thresh[:int(-z-shard_size-2*scale)] = 0
        break

如您所见,对象在顶部被剪切。这是一种笨拙的方法。在下一步中,
cv2.PCACompute()
用于找到对象的中心并确定其极值的方向。提供了
shard_size
,可以在对象极值的方向上绘制一条线

#compute geometry of object (center + line extrema)
mat = np.argwhere(thresh == 255)
mat[:, [0, 1]] = mat[:, [1, 0]]
mat = np.array(mat).astype(np.float32)
m, e = cv2.PCACompute(mat, mean = np.array([]))

#determine coordinates of object (center + line extrema)
center = tuple(m[0])
endpoint1 = tuple(m[0] - e[0] * shard_size/2)
endpoint2 = tuple(m[0] + e[0] * shard_size/2)

#draw line into object
red_color = (0, 0, 255)
coord1 = endpoint1
coord2 = endpoint2
cv2.circle(img, center, 1, red_color)
cv2.line(img, coord1, coord2, red_color)

#save output img
cv2.imwrite('output_img.png', img)


如何找到对象的极值而不是中心,这样我就不需要再给程序输入
碎片大小了?

在这里,我使用cv2.minareact()函数找到了对象的长度,并计算了沿质心的端点

minarealect函数为我们提供包围对象的矩形的中心、轴和角度。我使用角度信息旋转水平向量并生成直线的端点

#Finding the contours in the image
im2, contours, hierarchy = cv2.findContours(img,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)

#finding the minimum area rectangle that covers the blob
rect = cv2.minAreaRect(contours[0])
box = cv2.boxPoints(rect)
box = np.int0(box)
cv2.drawContours(img,[box],0,(0,0,255),2)

#Forming the line vector
v = np.matrix([[0], [1]])

#forming the rotation matrix to rotate the line vector
ang = rect[2]* np.pi / 180 #conversion to radians
rot = np.matrix([[np.cos(ang), -np.sin(ang)],[np.sin(ang), np.cos(ang)]])

#Rotating the horizontal vector
rv = rot*v

#half length of the line
lineSize = max(rect[1])*0.5

#extreme points of the line
p1 = tuple(np.array(rect[0] - lineSize*rv.T)[0].astype(int))
p2 = tuple(np.array(rect[0] + lineSize*rv.T)[0].astype(int))

cv2.line(img, p1, p2, (0,255,0), 2)

是否有类似于最接近的边界框(未对齐轴)?对不起,你的意思是什么?阈值操作后,你会看到一个二值图像-通常光像素包含一个ROI“感兴趣区域”,可以对其几何特性进行某些操作:面积、最小的封闭圆、,轴对齐的边界框、最小的边界框等。最后一个可能是拉出长轴长度的最佳选择。或者,可能有一个“最大直径”,它告诉或多或少相同的形状。