Анализ изображений, форма объекта, центр и экстремумы - PullRequest
0 голосов
/ 27 ноября 2018

Я написал программу для построения порога из изображения в градациях серого и нахождения его нижнего центра объекта.Это также используется для рисования геометрии (линии) в объекте.Функция cv2.PCACompute() используется для нахождения центра объекта.После того, как это сделано, я могу нарисовать линии, чтобы соответствовать приблизительной форме объекта и провести дальнейший анализ.

Итак:

Экстремумы объекта - это важная вещь, которую мне нужно найти, а не центр.Но для их расчета мне нужно нарисовать линию, исходящую из центра.Проблема в том, что мне нужно сообщить программе size объекта.Прямо сейчас я пытаюсь автоматизировать это, обнаруживая экстремумы объекта вместо центра.Интересно, можете ли вы помочь мне с этим?

Входное изображение:

enter image description here

Сначала строится порог, а верхний объект удаляетсяиз него:

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

enter image description here

Как видите, объект режется сверху.Это неуклюжий способ сделать это.На следующем шаге 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)

enter image description here

Как найти экстремумы объекта вместо центра, поэтому мне не нужно давать программе shard_size Введите больше?

1 Ответ

0 голосов
/ 27 ноября 2018

Здесь я нашел длину объекта с помощью функции cv2.minAreaRect () и вычислил конечные точки вдоль центроида.

Функция minAreaRect дает нам центр, оси и угол прямоугольника, который окружаетпредмет.Я использовал информацию угла для поворота горизонтального вектора и сгенерировал конечные точки линии

#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)

Output

...