Ограничивающая рамка блоба на изображении

У меня есть изображение в градациях серого с черным фоном и некоторые нечерные объекты на нем, например:

Теперь я хочу найти минимальную (прямоугольную) ограничивающую рамку для каждого объекта. Я могу предоставить отправную точку внутри каждого объекта, если это поможет.

Поскольку нет никаких причудливых порогов или чего-то еще, я бы хотел избежать чего-то вроде Canny для поиска контуров. Если пиксель не равен 0, он находится в капле.

Ищите алгоритмы трассировки краев. Если вы не знаете, сколько пятен, начните с чтения горизонтальных и вертикальных линий на изображении в поисках пятен. Как только вы найдете его, найдите край и обведите его. Затем продолжайте искать кляксы, удаляя те, которые вы уже нашли. Чем больше правил для больших двоичных объектов вы знаете (минимальный размер, количество больших двоичных объектов и т. д.), тем быстрее это будет работать. Я только что перечитал, у вас есть отправная точка в блоге. Посмотрите вниз оттуда, чтобы найти край, затем идите.

Flydog57 21.12.2020 16:41
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
1
1 179
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Независимо от того, что вы используете, вам все равно придется перебирать все пиксели. хотя Bitmap.GetPixel(x,y) в основном используется, но он очень медленный. но если вы заблокируете биты в памяти и зациклите массив байтов, это будет в сотни раз быстрее.

пожалуйста, взгляните на этот документ для блокировки битов изображения в памяти.

Реализация цикла самостоятельно не будет проблемой, я также знаком с битовой блокировкой. Я просто подумал, что такую ​​простую задачу, вероятно, можно решить с помощью некоторых существующих библиотечных функций, вместо того, чтобы самому изобретать велосипед. Что также библиотека, скорее всего, будет перебирать все пиксели, да, понятно. Но все же, зачем заново изобретать велосипед.

user3696412 21.12.2020 18:08

Я не уверен, существует ли такая библиотека или нет. Но если вы начали изобретать колесо, оно у вас уже есть.

Ashkan Mobayen Khiabani 21.12.2020 18:21

Или я бы все еще отлаживал какой-то странный пограничный случай. Версия @Carlos Melus отлично работает, поэтому для этого есть библиотечная функция. И дело не в том, что я провел время в ожидании ответа, рисуя что-то, а в это время я сделал кое-что еще. Так что в целом это было самое быстрое и чистое решение.

user3696412 21.12.2020 18:32
Ответ принят как подходящий

Чтобы нарисовать прямоугольники вокруг всего, что не является полностью черным на вашем изображении, вы можете сделать следующее:

imagefile = '/path/to/your/image'
img = cv2.imread(imagefile)

# Convert you image to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

# Threshold the image to extract only objects that are not black
# You need to use a one channel image, that's why the slice to get the first layer
tv, thresh = cv2.threshold(gray[:,:,0], 1, 255, cv2.THRESH_BINARY)

# Get the contours from your thresholded image
contours = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[0]

# Create a copy of the original image to display the output rectangles
output = img.copy()

# Loop through your contours calculating the bounding rectangles and plotting them
for c in contours:
    x, y, w, h = cv2.boundingRect(c)
    cv2.rectangle(output, (x,y), (x+w, y+h), (0, 0, 255), 2)
# Display the output image
plt.imshow(cv2.cvtColor(output, cv2.COLOR_BGR2RGB))

Другие вопросы по теме