- Оригинальный адрес:Edge Detection in Python
- Оригинальный автор:Ritvik Kharkar
- Перевод с:Программа перевода самородков
- Постоянная ссылка на эту статью:GitHub.com/rare earth/gold-no…
- Переводчик:lsvih
- Корректор:PingHGao, Amberlin1970
Обнаружение границ с помощью Python
В прошлом квартале я помогал преподавать курс Python в школе и многому научился в процессе обработки изображений. В этой статье я надеюсь поделиться некоторыми знаниями об обнаружении границ, включаятеорияи как использовать питонвыполнитьобнаружение края.
Зачем обнаруживать края?
Первое, что мы должны понять, это:«Зачем беспокоиться об обнаружении краев?»Помимо крутых эффектов, почему обнаружение краев является практичным методом? Чтобы лучше ответить на этот вопрос, подумайте об этом и сравните изображение вертушки ниже с его «изображением только с края»:
Как видите, исходное изображение слева имеет множество цветов и оттенков, тогда как «изображение только по краям» справа черно-белое. Если кто-то спросит, какому изображению нужно больше места для хранения, вы обязательно ответите ему, что исходное изображение займет больше места. Вот что такое обнаружение краев: при обнаружении краев на изображении большая часть деталей отбрасывается, что приводит к «более светлому» изображению.
Таким образом, без необходимости сохранять все сложные детали изображения и"заботьтесь только об общей форме изображения", обнаружение границ может быть очень полезным.
Как сделать обнаружение краев — математика
Прежде чем обсуждать реализацию кода, давайте кратко рассмотрим математику, лежащую в основе обнаружения границ. Как люди, мы довольно хорошо распознаем «края» на изображениях, так как же заставить компьютер делать то же самое?
Во-первых, представьте очень простое изображение с черным квадратом на белом фоне:
В этом примере, поскольку мы имеем дело с черно-белыми изображениями, мы можем рассмотреть возможность использования значения каждого пикселя изображения как0 (черный)или1 (белый)Представлять. В дополнение к черно-белым изображениям та же самая теория прекрасно применима к цветным изображениям.
Теперь нам нужно определить, является ли пиксель, выделенный зеленым цветом на изображении выше, частью края этого изображения. Как люди, мы, безусловно, можем признать этодаКрая изображения, но как заставить компьютер использовать соседние пиксели для получения того же результата?
Мы устанавливаем маленькую рамку размером 3 x 3 пикселя с центром в пикселе, выделенном зеленым цветом, обозначенном красным на рисунке. Затем «примените» фильтр к этому маленькому окошку:
На изображении выше показан фильтр, который мы собираемся «применить». Сначала это может показаться загадочным, поэтому давайте подробнее рассмотрим, что он делает: когда мы говорим «применить фильтр к небольшому локальному участку пикселей», мы имеем в виду, что каждый пиксель в красном прямоугольнике связан с фильтром. пиксель, соответствующий его положению в устройстве. Итак, верхний левый пиксель в красном поле имеет значение 1, а фильтр имеет значение -1 для верхнего левого пикселя, и они перемножаются, чтобы получить -1, что и показывает верхний левый пиксель в результирующее изображение. Таким образом получается каждый пиксель результирующего графа.
Следующий шаг — суммировать все значения пикселей в отфильтрованном результате, чтобы получить -4. Обратите внимание, что -4 на самом деле является «минимальным» значением, которое мы можем получить, применив этот фильтр (поскольку значение пикселя в исходном изображении может быть только между 0 и 1). Следовательно, когда получено минимальное значение -4, мы можем знать, что соответствующий пиксель является квадратом на изображении.верхний вертикальный крайчасть.
Чтобы лучше понять это преобразование, мы можем увидеть, что происходит, когда мы применяем этот фильтр к пикселю на нижнем краю квадрата на изображении:
Как видите, у нас получился аналогичный предыдущему результат, после сложения результата получаем 4, что и можно получить, применив данный фильтрмаксимальное значение. Итак, поскольку мы получили максимальное значение 4, мы знаем, что этот пиксель является квадратом на изображении.Нижний вертикальный крайчасть.
Чтобы сопоставить эти значения с диапазоном 0-1, мы можем просто добавить к нему 4 и разделить на 8, что сопоставит -4 с 0 (чернить), который отображает 4 в 1 (белый). Поэтому мы называем этот фильтр какВертикальный фильтр Собеля, который можно использовать для простого обнаружения вертикальных краев на изображении.
Как обнаружить горизонтальные края? Проще говорявертикальный фильтрТранспонирование (переворот диагонали его числовой матрицы) дает новый фильтр, который можно использовать для обнаружения горизонтальных краев.
Если нам нужно одновременно определить горизонтали, вертикали и края между ними, мы можем использоватьОценка вертикального фильтра и оценка горизонтального фильтра объединены, этот шаг будет отражен в последующем коде.
Я надеюсь, что вышеизложенное прояснило эти теории! Давайте посмотрим, как реализован код.
Как сделать обнаружение края - код
Сначала сделайте некоторые настройки:
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
# 定义纵向过滤器
vertical_filter = [[-1,-2,-1], [0,0,0], [1,2,1]]
# 定义横向过滤器
horizontal_filter = [[-1,0,1], [-2,0,2], [-1,0,1]]
# 读取纸风车的示例图片“pinwheel.jpg”
img = plt.imread('pinwheel.jpg')
# 得到图片的维数
n,m,d = img.shape
# 初始化边缘图像
edges_img = img.copy()
- Вы можете заменить «pinwheel.jpg» в коде на любой другой файл изображения, край которого вы хотите найти! Вы должны убедиться, что этот файл и код находятся в одном рабочем каталоге.
Затем напишите сам код обнаружения края:
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
# 定义纵向过滤器
vertical_filter = [[-1,-2,-1], [0,0,0], [1,2,1]]
# 定义横向过滤器
horizontal_filter = [[-1,0,1], [-2,0,2], [-1,0,1]]
# 读取纸风车的示例图片“pinwheel.jpg”
img = plt.imread('pinwheel.jpg')
# 得到图片的维数
n,m,d = img.shape
# 初始化边缘图像
edges_img = img.copy()
# 循环遍历图片的全部像素
for row in range(3, n-2):
for col in range(3, m-2):
# 在当前位置创建一个 3x3 的小方框
local_pixels = img[row-1:row+2, col-1:col+2, 0]
# 应用纵向过滤器
vertical_transformed_pixels = vertical_filter*local_pixels
# 计算纵向边缘得分
vertical_score = vertical_transformed_pixels.sum()/4
# 应用横向过滤器
horizontal_transformed_pixels = horizontal_filter*local_pixels
# 计算横向边缘得分
horizontal_score = horizontal_transformed_pixels.sum()/4
# 将纵向得分与横向得分结合,得到此像素总的边缘得分
edge_score = (vertical_score**2 + horizontal_score**2)**.5
# 将边缘得分插入边缘图像中
edges_img[row, col] = [edge_score]*3
# 对边缘图像中的得分值归一化,防止得分超出 0-1 的范围
edges_img = edges_img/edges_img.max()
Несколько замечаний:
- Мы не можем создать полную рамку 3 x 3 на граничных пикселях изображения, поэтому вокруг изображения будет тонкая рамка.
- Поскольку мы обнаруживаем как горизонтальные, так и вертикальные границы, мы можем напрямую разделить исходные вертикальные и горизонтальные оценки на 4 (вместо добавления 4 и деления на 8, как описано выше). Это изменение безобидно, но оно может лучше подчеркнуть края изображения.
- Объединение вертикальной оценки с горизонтальной оценкой может привести к тому, что окончательная предельная оценка выйдет за пределы диапазона 0–1, поэтому в конце итоговую оценку необходимо повторно нормализовать.
Выполнение приведенного выше кода на более сложном изображении:
Получите результат обнаружения края:
Это все для этой статьи! Надеюсь, вы узнали что-то новое и следите за новостями о новых статьях по науке о данных~
Если вы обнаружите ошибки в переводе или в других областях, требующих доработки, добро пожаловать наПрограмма перевода самородковВы также можете получить соответствующие бонусные баллы за доработку перевода и PR. начало статьиПостоянная ссылка на эту статьюЭто ссылка MarkDown этой статьи на GitHub.
Программа перевода самородковэто сообщество, которое переводит высококачественные технические статьи из ИнтернетаНаггетсДелитесь статьями на английском языке на . Охват контентаAndroid,iOS,внешний интерфейс,задняя часть,блокчейн,продукт,дизайн,искусственный интеллектЕсли вы хотите видеть более качественные переводы, пожалуйста, продолжайте обращать вниманиеПрограмма перевода самородков,официальный Вейбо,Знай колонку.