Как нарисовать линию вокруг цветных пикселей изображения с определенным смещением?

Я использую opencv для Javascript для создания исходного изображения, которое я помещаю в контекст холста через putImageData.

Мне нужно нарисовать линию вокруг красной части изображения на расстоянии около 20 пикселей от красной. Второе изображение - это то, что мне нужно ... нарисованное от руки, но, надеюсь, вы поняли идею.

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

Как нарисовать линию вокруг цветных пикселей изображения с определенным смещением?Как нарисовать линию вокруг цветных пикселей изображения с определенным смещением?


Обновлять: По запросу комментатора, вот пример того, почему расширение не работает.

// Dilate the image
let src = cv.imread('canvasOffset');
let dst = new cv.Mat();
let M = cv.Mat.ones(40, 40, cv.CV_8U);
let anchor = new cv.Point(-1, -1);
cv.dilate(src, dst, M, anchor, 1, cv.BORDER_CONSTANT, 
cv.morphologyDefaultBorderValue());
cv.imshow('canvasOffset', dst);
src.delete(); dst.delete(); M.delete()

Как нарисовать линию вокруг цветных пикселей изображения с определенным смещением?

dilate был моей первой мыслью. Можете ли вы показать нам, как вы его используете, и привести пример, когда он не дает желаемых результатов?
beaker 02.06.2018 18:52

@beaker Я обновил свой пост по вашему запросу.

agileadam 03.06.2018 17:53

«Не кажется надежным», что это значит? Расширение - правильный подход. Было бы немного быстрее, чем решение Джеру. Но вы должны использовать круговой элемент структурирования, чтобы получить желаемый эффект (приводит к одинаковому смещению во всех направлениях).

Cris Luengo 03.06.2018 22:17

Ого! Спасибо, @CrisLuengo! Я просто переключил элемент структурирования расширения на MORPH_ELLIPSE, и он мгновенно сделал именно то, что мне нужно.

agileadam 04.06.2018 02:21
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
4
92
2

Ответы 2

У меня есть простое решение, реализованное на Python.

  1. Сначала я преобразовал данное изображение в двоичное изображение, где красный объект является интересующей областью (белый).

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

  1. Я нашел контуры на этом черном изображении и нарисовал полученные контуры на исходном изображении. На этот раз я нарисовал контуры без толщины.

(Как я уже сказал, код написан на Python, если вы хотите, чтобы я им поделился)

import cv2
import numpy as np
import os

path = r'C:\Users\Desktop\Stack\contour'
im = cv2.imread(os.path.join(path, 'handle.jpg'))
im = cv2.resize(im, (0, 0), fx=0.5, fy=0.5)         #--- resizing the image
im2 = im.copy()    #--- having another copy of the original image                       

imgray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
ret2, th2 = cv2.threshold(imgray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
cv2.imshow('th2.jpg', th2)     #--- Image 1

_, contours, hierarchy = cv2.findContours(th2, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnt = contours[0]

mask = np.zeros_like(im)
cv2.drawContours(mask, contours, -1, (255, 255, 255), 33)
cv2.imshow('mask.jpg', mask)    #--- Image 2

ret2, mask_th2 = cv2.threshold(mask[:,:,1], 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
_, contours1, hierarchy = cv2.findContours(mask_th2, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(im2, contours1, -1, (0, 0, 0), 2)
cv2.imshow('final.jpg', im2)    #--- Image 3

cv2.waitKey(0)
cv2.destroyAllWindows()

Это здорово! Код на Python, безусловно, мне поможет. Большая часть моей работы с opencv была на Python; Я пробую использовать библиотеку javascript в качестве доказательства концепции.

agileadam 03.06.2018 14:18

@agileadam Привет. Спасибо за интерес. Я добавил код.

Jeru Luke 03.06.2018 15:15

Спасибо, Джеру. Попробую пересоздать на JS.

agileadam 03.06.2018 17:53

Благодаря Крису Луенго это решено.

Мне удалось использовать расширение OpenCV с эллиптическим элементом структурирования. Он делает именно то, что мне нужно.

Для холста "canvasOffset", содержащего исходное изображение:

let src = cv.imread('canvasOffset');
let dst = new cv.Mat();
let M = new cv.Mat();
let ksize = new cv.Size(25, 25);
M = cv.getStructuringElement(cv.MORPH_ELLIPSE, ksize);
let anchor = new cv.Point(-1, -1);
cv.dilate(src, dst, M, anchor, 1, cv.BORDER_CONSTANT, cv.morphologyDefaultBorderValue());
cv.imshow('canvasOffset', dst);

Результат:

это действительно более быстрое решение

Jeru Luke 09.06.2018 13:35

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