Расчет периметра органической формы - PullRequest
2 голосов
/ 03 июля 2019

Я использовал Python для вычисления областей или неправильных форм на черно-белых изображениях путем умножения количества белых пикселей на площадь отдельного пикселя.

Однако теперь мне также нужно вычислить периметр этой неправильной формы. Форма может иметь отверстия в нем. Вот пример изображения:

Sample Image

Есть идеи, как мне решить эту проблему? Я не полный новичок, но я и не кодер. Наверное, опытный новичок.

Заранее спасибо.

EDIT: Есть некоторые вещи, которые я до сих пор не понимаю, но это сработало для меня:

import cv2
import numpy as np



def import_image(filename):
    original_image = cv2.imread(filename, cv2.IMREAD_UNCHANGED)
    return original_image

#getting original file
img = import_image('PerimeterImage.jpg')

#converting to gray
img_grey = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

#set a thresh
thresh = 1

#get threshold image
ret,thresh_img = cv2.threshold(img_grey, thresh, 255, cv2.THRESH_BINARY)

#find contours
image, contours, hierarchy = cv2.findContours(thresh_img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

#create an empty image for contours
img_contours = np.zeros(img.shape)

perimeter = 0

for c in contours:
    peri = cv2.arcLength(c, True)
    approx = cv2.approxPolyDP(c, 0.0001 * peri, True)
    cv2.drawContours(img_contours, [approx], -1, (0, 0, 255), 1)
    perimeter = perimeter + peri

print(f'Perimeter = {int(round(perimeter,0))} pixels')

#show image
cv2.imshow('Output', img_contours)
cv2.waitKey(0)

#save image
cv2.imwrite('contours.jpg', img_contours) 

Ответы [ 2 ]

1 голос
/ 04 июля 2019

Просто используйте cv.findContours, чтобы найти контуры белой области, как правило, вам нужно будет сделать порог до findContours, но, поскольку ваше изображение черно-белое, возможно, вы можете его игнорировать.

Для периметра просто используйте cv.arcLength для требуемого контура.

0 голосов
/ 03 июля 2019

Я не думаю, что есть простой способ сделать это.

Я включил два очень похожих подхода. Оба подхода используют библиотеку opencv и ее магию. Второй - в основном там, если вы заинтересованы в упрощенной версии того, как это можно сделать.

Метод 1 (предпочтительно)

Я думаю, это будет самый простой вариант для вас.

import cv2 as cv
img = cv.imread('img.jpg', 0) #Get your image
edges = cv2.Canny(img,100,200)

Затем вы можете посчитать пиксели, чтобы получить периметр.

Более подробную информацию об этом можно найти здесь .


Метод 2
  1. Сначала используйте Laplacian, чтобы получить величину градиента изображения.
laplacian = cv.Laplacian(img, cv.CV_64F)
  1. Затем вы можете перейти к шагу 3 или сделать это для получения более точных результатов. Используйте не максимальное подавление, чтобы сделать края тонкими на 1 пиксель. Это непросто, но вы можете найти объяснение идеи, стоящей за этим, по ссылке выше.

  2. Подсчитайте оставшиеся пиксели, чтобы получить периметр.

Вы должны знать, что это будет несовершенным, так как такие вещи, как черные пятна внутри ваших объектов, также будут учитываться. Если вы не хотите что, вы можете сделать операцию закрытия перед не максимальным подавлением, используя:

closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)

Примечание: Эти решения предполагают, что ваши входные изображения всегда будут такими же, как вы предоставили. Если это не так, то некоторые изменения должны быть сделаны.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...