1. Обзор проблемы
Искусственный интеллект стимулировал спрос на таланты в области компьютерного зрения.Как среда разработки для приложений компьютерного зрения, OpenCV становится все более и более популярным, и рыночный спрос значительно увеличился. Поэтому очень важно и нужно изучать технологию Opencv на базе изучения Python. Эта технология не только имеет зрелую структуру обучения, но и имеет широкий спектр приложений. Изучение некоторых технологий Opencv имеет необычайное значение для студентов колледжей.
2. Основные требования к разработке учебных программ
Основное содержание отчета по дизайну включает как минимум три части: обложку, текст и список литературы.
1. обложка
Обложка заполняется по шаблону и не может быть изменена произвольно.
2. текст
Основная часть отчета по проектированию состоит из следующих частей:
(1) Предыстория, описание проблемы
Опишите проблему, для решения которой требуется программирование.
(2) Основные требования
Укажите конкретные требования, которым должна соответствовать программа.
(3) Анализ спроса
Сформулируйте задачу программирования в недвусмысленных формулировках, подчеркнув, что делает программа? и четко заявляет:
форма ввода и диапазон вводимого значения;
форма выпуска;
Функции, которые может выполнять программа;
Тестовые данные: включая правильный ввод и его выходные результаты, а также неправильный ввод и его выходные результаты.
(4) Эскизный дизайн
Объясните ход основной программы в этой программе и иерархические (вызывающие) отношения между программными модулями.
(5) Детальный проект
Реализуйте все типы данных, определенные в эскизном проекте, дайте список ключевых частей исходной программы и потребуйте, чтобы программа имела достаточное количество комментариев, по крайней мере, значение каждого параметра функции и значение возвращаемого значения функции.
(6) Отладочный анализ
Содержание включает в себя: способы решения проблем, возникающих в процессе отладки, а также обзор, обсуждение и анализ проектирования и реализации;
(7) Инструкции для пользователя
Объясните, как использовать написанную вами программу, подробно описав шаги для каждого шага.
(8) Результаты испытаний
Разработайте тестовые данные или предоставьте конкретные тестовые данные. Тестовые данные должны быть полными и точными, а функции разработанной программы могут быть полностью протестированы.
(9) Резюме
(10) Ссылки
Перечислите соответствующие источники и книги для справки.
3. Анализ требований к дизайну распознавания Opencv
В теоретических исследованиях распознавание объектов было горячей темой исследований в области компьютерного зрения за последние десять лет. В топовых конференциях и журналах ежегодно появляется множество смежных работ в этом направлении. В некоторых усовершенствованных сценариях приложений, таких как распознавание лиц и отпечатков пальцев, были относительно зрелые приложения. Изучая соответствующие теории распознавания объектов, в этой статье реализуется красочный космический рисунок на основе дизайна OpenCV, чтобы попытаться решить задачу распознавания цветового пути.Основная работа заключается в следующем: Схема распознавания объектов на основе цветовых характеристик: первое содержание исследования эта статья посвящена распознаванию цвета. Связанные алгоритмы в основном состоят из двух частей: извлечение признаков и сопоставление признаков. Глубокое понимание алгоритмов обнаружения признаков помогает выбрать и оптимизировать соответствующий алгоритм для конкретных сценариев практических приложений.
4. Сводный анализ дизайна красочного космического рисунка
Основная цель этого проекта - считывать визуальную информацию, отображаемую на камеру через камеру, анализировать цвет, который необходимо распознать, помечать цвет точками и непрерывно рисовать точки для достижения конечного эффекта рисования. Среди них можно использовать восстановление вызова окна, переворачивание окна, коррозию для устранения шумовых пятен, расширение для соединения области, разделенной шумом и тенью, операцию открытия, чтобы сначала выветрить, а затем расширение ; "Вежливость"; "Черная шляпа"; регулировка размера; слияние окон; добавление кнопок для настройки параметров; пороговое значение и другие приемы. Благодаря изучению различных модулей они интегрируются в общий проект. Этот проект в основном изучает и завершает проект, основанный на знаниях Opencv, используемых в различных главах официальной документации Opencv на Github.
4.1 Среда разработки красочных космических рисунков
Модель компьютера: Версия Mechanical Revolution X6Ti Системная ОС: Windows 10 Professional Edition Номер версии 20H2 Дата установки 2020/9/10 Версия ОС 19042.610 Пакет возможностей Windows 120.2212.31.0 Используемое программное обеспечение: PyCharm 2020.1 x64, VSCode, Python3.6
4.2 Технология Opencv
OpenCV — это кроссплатформенная библиотека программного обеспечения для компьютерного зрения и машинного обучения, выпущенная под лицензией BSD (с открытым исходным кодом) и может работать в операционных системах Linux, Windows, Android и Mac OS. [1] Он легкий и эффективный — он состоит из ряда функций C и небольшого количества классов C++, предоставляет интерфейсы на таких языках, как Python, Ruby и MATLAB, и реализует множество общих алгоритмов обработки изображений и компьютерное зрение. OpenCV написан на языке C++, имеет интерфейсы C++, Python, Java и MATLAB и поддерживает Windows, Linux, Android и Mac OS. OpenCV в основном ориентирован на приложения машинного зрения в реальном времени и использует инструкции MMX и SSE, когда они доступны, Обеспечивает поддержку C#, Ch, Ruby и GO. OpenCV может работать на таких платформах, как Windows, Android, Maemo, FreeBSD, OpenBSD, iOS, Linux и Mac OS. Пользователи могут получить официальную версию на SourceForge или получить версию для разработки в SVN. OpenCV также использует CMake. Некоторые базовые классы из DirectShow SDK необходимы для компиляции частей OpenCV, связанных с вводом данных с камеры в Windows. SDK доступен в предварительно скомпилированном Microsoft Platform SDK (или DirectX SDK 8.0–9.0c / DirectX Media SDK до версии 6.0) в подкаталоге Samples\Multimedia\DirectShow\BaseClasses. Python, язык программирования общего назначения, созданный Гвидо ван Россумом, быстро стал очень популярным, главным образом благодаря своей простоте и читабельности кода. Это позволяет программистам выражать идеи в меньшем количестве строк кода без ущерба для удобочитаемости. Python работает медленно по сравнению с такими языками, как C/C++. Тем не менее, Python можно легко расширить с помощью C/C++, что позволяет нам писать ресурсоемкий код на C/C++ и создавать оболочки Python, которые можно использовать в качестве модулей Python. Это дает нам два преимущества: во-первых, код работает так же быстро, как исходный код C/C++ (поскольку это фактический код C++, работающий в фоновом режиме), и, во-вторых, код на Python писать проще, чем на C/C++. OpenCV-Python — это оболочка Python для исходной реализации OpenCV C++. OpenCV-Python используетNumpy, высокооптимизированная библиотека для числовых операций с использованием синтаксиса в стиле MATLAB. Все структуры массивов OpenCV преобразуются в массивы Numpy и из них. Это также упрощает интеграцию с другими библиотеками, использующими Numpy, такими как SciPy и Matplotlib.
4.3 Общий дизайн структуры красочной космической живописи
На рис. 1 показана общая структура цветного пространственного рисунка, который обычно делится на четыре модуля: считывание кадра изображения с камеры, получение цвета, точка базовой единицы и реализация пути рисования. Камера, считывающая модуль кадра изображения, в основном создает окно на экране, в котором рисуется траектория рисования; в модуле получения цвета в основном заимствует коррозию в cv2 для устранения шумовых пятен; расширение и другие функции используются для идентификации требуемый цвет, получение и идентификация; в основном блоке модуля он в основном рисует круг с цветом, этот круг является базовой единицей для рисования пути, и путем непрерывного повторения этого круга рисуется путь; в реализации рисунка путь В модуле точки базового блока постоянно повторяются, в основном, с помощью функций для реализации рисования пути.
5. Детальный дизайн красочной космической краски
В четырех модулях камера сначала считывает графический дизайн кадра, затем выполняет простую идентификацию, а затем добавляет кнопку регулировки для реализации кнопки перемещения для получения наилучшего эффекта идентификации, чтобы получить значение RGB цвета, которое необходимо идентифицировать. Через полученное значение RGB можно снова вызвать функцию Opencv, чтобы реализовать рисование базовой единичной окружности, а затем соединить их для реализации реализации рисования пути. В процессе требуется несколько экспериментов и отладка, и каждый модуль может быть изменен несколько раз, от первоначального проекта до написания кода, написания алгоритма и оптимизации кода алгоритма.
5.1 Конструкция рамки изображения для считывания с камеры
Нам нужно найти наш цвет, и нам нужно использовать веб-камеру, тогда мы можем разместить разные точки, где бы ни был найден цвет, чтобы создать пример рисования. Итак, первое, что нам нужно, это веб-камера, поэтому, согласно первой главе официальной документации, мы вызываем нашу веб-камеру.
import cv2
frameWidth = 640 # chapter1
frameHeight = 480 # chapter1
cap = cv2.VideoCapture(1) # chapter1
cap.set(3, frameWidth) # chapter1
cap.set(4, frameHeight) # chapter1
cap.set(10, 150) # chapter1
while True:
success, img = cap.read()
cv2.imshow("Result", img)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
Сначала нам нужно импортировать библиотеку, импортировать библиотеку Opencv через import cv2. Мы устанавливаем две переменные, одна — это ширина окна, равная 640, а другая — высота окна, равная 480, что достигается за счет frameWidth = 640 и frameHeight = 480. Затем установите идентификационные номера для ширины и высоты окна соответственно 3 и 4. Заодно выставили яркость окна.После тестирования мы выбрали яркость 150 как яркость экрана окна. Функция VideoCapture — это функция, которая вызывает камеру, для не вызова параметр равен 1, а для вызова — параметр 0. Сначала мы устанавливаем его в 1, а когда нам нужно вызвать, снова устанавливаем в 0.
Затем мы циклически получаем положение изображения, используем функцию imshow и устанавливаем имя окна на Result. Чтобы иметь функцию выхода, мы установили, чтобы нажать «Q» на клавиатуре для выхода.
На данный момент мы тестируем, и ожидаемый эффект — реальная камера.
Запускаем программу и тестируем камеру.Результат камера читает успешно.Здесь отображаются четыре пальца.На экране также видно четыре пальца.Тест прошел успешно.
Затем проверьте функцию выхода из программы, нажмите Q на клавиатуре, чтобы выйти, результатом проверки будет успешный выход, когда метод ввода - китайский режим, вам нужно перейти в английский режим, а затем нажмите Q, чтобы выйти.
5.2 Получить цветовой дизайн
После того, как окно успешно создано, происходит приобретение цвета. Все, что нам нужно сделать, это найти наш цвет, чтобы найти наш цвет. Нам нужно ввести код для определения цвета.Содержание этой части описано в главе 7 официального документа.Мы можем прочитать соответствующий контент для изучения функций и написания кода. Нам нужно определить верхний и нижний пороги, а также преобразовать окно в пространство HSV. В коде нам нужно определить функцию для поиска нашего цвета, конкретный код выглядит следующим образом.
def findColor(img, myColors, myColorValues): # 查找颜色函数
imgHSV = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) # chapter2
count = 0 # 计数器来计算实际计数多少次
newPoints = []
for color in myColors:
lower = np.array(color[0:3]) # chapter2 这里改为取前三个值
upper = np.array(color[3:6]) # chapter2 这里改为取3-6的值
mask = cv2.inRange(imgHSV, lower, upper) # chapter2
x, y = getContours(mask) # 调用获取轮廓的函数
# 绘制圆,中心点由x和y坐标确定,半径定为8,获取识别的颜色,然后进行圆的填充
cv2.circle(imgResult, (x, y), 8, myColorValues[count], cv2.FILLED)
# 在计数前,如果x和y不等于0,每次记录新的点进行追加
if x != 0 and y != 0:
newPoints.append([x, y, count])
count += 1
# cv2.imshow(str(color[0]),mask)
return newPoints
На первом этапе мы сначала выполняем тест обнаружения, устанавливаем вход функции в значение ing, а затем преобразуем его в пространство HSV. Чтобы определить, работает ли он правильно, мы добавляем cv2.imshow() для проверки.
def findColor(img): # 查找颜色函数
imgHSV = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
lower = np.array([h_min,s_min,v_min])
upper = np.array([h_max,s_max,v_max])
mask = cv2.inRange(imgHSV,lower,upper)
cv2.imshow("img",mask)
Cv2.imshow("img",mask) здесь только для тестирования, позже он будет удален.
Мы не хотим найти только один цвет, мы хотим найти разные цвета, поэтому, когда мы вызываем функцию findColor(), мы хотим найти разные типы цветов и любые существующие цвета и получить их в качестве вывода. Таким образом, мы можем определить некоторый контент в виде списка над функцией, например, минимальное и максимальное значение цвета. Мы определяем список с именем myColors, который в основном представляет собой список цветов, которые мы хотим обнаружить. Так что нам нужно давать минимальное и максимальное значения насыщенности оттенка при присвоении значений. Здесь мы выбираем некоторые определенные цвета, такие как красный, синий, зеленый и другие цвета, и реализуем заданное значение резервирования цвета. Это может помочь нам выбрать правильное значение оттенка-насыщенности с помощью веб-камеры.
Цветовой код для бронирования обнаружения ниже
import cv2
import numpy as np
frameWidth = 640
frameHeight = 480
cap = cv2.VideoCapture(1)
cap.set(3, frameWidth)
cap.set(4, frameHeight)
cap.set(10,150)
def empty(a):
pass
cv2.namedWindow("HSV")
cv2.resizeWindow("HSV",640,240)
cv2.createTrackbar("HUE Min","HSV",0,179,empty)
cv2.createTrackbar("SAT Min","HSV",0,255,empty)
cv2.createTrackbar("VALUE Min","HSV",0,255,empty)
cv2.createTrackbar("HUE Max","HSV",179,179,empty)
cv2.createTrackbar("SAT Max","HSV",255,255,empty)
cv2.createTrackbar("VALUE Max","HSV",255,255,empty)
while True:
_, img = cap.read()
imgHsv = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
h_min = cv2.getTrackbarPos("HUE Min","HSV")
h_max = cv2.getTrackbarPos("HUE Max", "HSV")
s_min = cv2.getTrackbarPos("SAT Min", "HSV")
s_max = cv2.getTrackbarPos("SAT Max", "HSV")
v_min = cv2.getTrackbarPos("VALUE Min", "HSV")
v_max = cv2.getTrackbarPos("VALUE Max", "HSV")
print(h_min)
lower = np.array([h_min,s_min,v_min])
upper = np.array([h_max,s_max,v_max])
mask = cv2.inRange(imgHsv,lower,upper)
result = cv2.bitwise_and(img,img, mask = mask)
mask = cv2.cvtColor(mask, cv2.COLOR_GRAY2BGR)
hStack = np.hstack([img,mask,result])
#cv2.imshow('Original', img)
#cv2.imshow('HSV Color Space', imgHsv)
#cv2.imshow('Mask', mask)
#cv2.imshow('Result', result)
cv2.imshow('Horizontal Stacking', hStack)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
В приведенном здесь коде в основном используется содержание главы 7 официального документа по кодированию. Основная цель состоит в том, чтобы интегрировать в кнопку оригинальную функцию ручной настройки.Когда мы вызываем кнопку для перемещения, экран может быть преобразован в пространство HSV, и можно легко получить характерный образец цвета. На основе кода на рисунке 3 добавьте интеграцию кнопок, и установите верхний и нижний предельные значения кнопок соответственно, чтобы регулировка имела определенный диапазон.
Мы устанавливаем для cap = cv2.VideoCapture(1) значение cap = cv2.VideoCapture(0), а затем запускаем код для проверки.
Верхнее окно — это окно обнаружения, левое нижнее — вывод значения цвета RGB, а правое — кнопка настройки.
Сначала мы выполняем обнаружение красного цвета, а затем выполняем обнаружение синего и зеленого.Красный и синий в основном используют красную ручку и синий, а зеленый в основном использует зеленые части над корректирующей лентой.
В результате обнаружения красного цвета мне нужно, чтобы красный цвет был белым на изображении, а остальные части оставались черными.
Мы можем видеть, что на картинке я настроил параметры, чтобы оставить его белым, окончательный вывод равен 0, значение HUE Min равно 0, значение SAT Min равно 91, значение VALUE Min равно 0, значение HUE Max равно 12, а значение SAT равно 0. И Max, и VALUE Max имеют значение 255.
Но цвет на руке определяется. Итак, нам нужно настроить значение HUE Max, мы устанавливаем его на 9, и цвет руки эффективно уменьшается.
Итак, мы записали нужные нам значения, 0,91,0,9,255,255. Так что добавьте эти значения в список myColor.
В результате обнаружения синего мне нужно, чтобы синий цвет оставался белым на изображении, а остальные части старались оставить черными.
Мы видим, что на картинке я скорректировал параметры, чтобы он оставался белым, конечный результат равен 97, минимальное значение HUE равно 97, минимальное значение SAT равно 107, минимальное значение VALUE равно 36, максимальное значение HUE равно 179, а значение SAT — 107. Максимальное значение — 255, а максимальное значение VALUE — 193.
Но ближайший окружающий цвет определяется, и нам нужно внести коррективы, чтобы сделать его как можно более оптимальным.
После настройки получаем окончательное значение 104 100 33 174 255 226. Добавьте его в список myColor.
В результате обнаружения зеленого цвета мне нужно, чтобы зеленый цвет оставался белым на изображении, а остальные части оставались черными.
Зеленые параметры проще настроить и не требуют вторичной оптимизации, наши параметры 77,150,0,91,255,255. Добавьте его в список myColor.
Затем мы получаем минимальное и максимальное значения оттенка и насыщенности для трех цветов в нашем списке myColor.
myColors = [[0, 91, 0, 9, 255, 255],
[104, 100, 33, 174, 255, 226],
[77, 150, 0, 91, 255, 255]]
Теперь мы можем просто создать маску.Во-первых, нам нужно импортировать библиотеку Numpy.Установите имя библиотеки numpy на np, импортировав numpy как np.
import cv2
import numpy as np
frameWidth = 640 # chapter1
frameHeight = 480 # chapter1
cap = cv2.VideoCapture(0) # chapter1
cap.set(3, frameWidth) # chapter1
cap.set(4, frameHeight) # chapter1
cap.set(10, 150) # chapter1
myColors = [[0, 91, 0, 9, 255, 255], # 要拥有最小和最大色相和饱和度值
[104, 100, 33, 174, 255, 226],
[77, 150, 0, 91, 255, 255]]
def findColor(img): # 查找颜色函数
imgHSV = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
lower = np.array([h_min, s_min, v_min])
upper = np.array([h_max, s_max, v_max])
mask = cv2.inRange(imgHSV, lower, upper)
cv2.imshow("img", mask)
while True:
success, img = cap.read()
cv2.imshow("Result", img)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
Затем нам нужно подставить требуемые значения в нижнее, верхнее и значение маски. Нижний представляет минимальное значение оттенка и насыщенности, которое является первыми тремя значениями каждого элемента myColor, а верхний представляет максимальное значение насыщенности оттенка, которое является последними тремя значениями каждого элемента myColor. Таким образом, нам нужно только прочитать каждую часть myColor.Например, мы сначала читаем красный, затем нижний параметр должен быть установлен следующим образом: нижний = np.array(myColors[0][0:3]), читать myColor элемента первого значения в третье значение, тогда нам нужно использовать myColor в качестве входного значения функции findColor для вызова функции, установить def findColor(img,myColors). Точно так же нам нужно сделать те же настройки в верхнем, например, верхнем = np.array(myColors[0][3:6]). Наконец, в цикле while необходимо вызвать функцию findColor.
while True:
success, img = cap.read()
findColor(img, myColors)
cv2.imshow("Result", img)
if cv2.waitKey(1) & 0xFF == ord('q'):
Break
Затем запустите программу для проверки.Мы видим, что обнаружение красного нормальное, но это только обнаружение красного, нам также нужно обнаружить все цвета в списке, для этого нам нужно добавить цикл for для обхода переменной цвета в myColor, а затем использовать цвет [0: 3] и цвет [3: 6] вместо исходного значения, и, наконец, поскольку существует несколько разных окон, поэтому имя окна должно быть другим, поэтому мы используем функцию str, чтобы установить имя окна на первое значение каждого элемента в значении myColor, равное 0, 104 и 77 соответственно.
def findColor(img,myColors): # 查找颜色函数
imgHSV = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
for color in myColors:
lower = np.array(color[0:3])
upper = np.array(color[3:6])
mask = cv2.inRange(imgHSV, lower, upper)
cv2.imshow(str(color[0]), mask)
Запустите код, чтобы проверить его.Как видите, мы отображаем три цвета одновременно, окна слева направо — красный, синий и зеленый.
Если нам нужно добавить больше цветов, мы можем напрямую добавить их значения оттенка/насыщенности в список myColor, а затем мы можем напрямую их идентифицировать.
Теперь, когда часть теста завершена, мы можем удалить cv2.imshow(str(color[0]),mask), закомментировав.
5.3 Точечный дизайн основного блока
Теперь нам нужно найти, где на изображении находится объект, который мы хотим обнаружить, для этого нам нужно получить контур, поэтому нам нужно аппроксимировать окружающую ограничивающую рамку, чтобы мы могли найти местоположение объекта. Здесь обратитесь к главе 8 официального документа для получения информации о функции получения ограничивающей рамки.
def getContours(img): # chapter8
contours, hierarchy = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) # chapter8
x, y, w, h = 0, 0, 0, 0
for cnt in contours:
area = cv2.contourArea(cnt)
if area > 500:
# cv2.drawContours(imgResult, cnt, -1, (255, 0, 0), 3)
peri = cv2.arcLength(cnt, True)
approx = cv2.approxPolyDP(cnt, 0.02 * peri, True) # chapter8
x, y, w, h = cv2.boundingRect(approx) # chapter8
return x + w // 2, y # 返回尖端的最高点和中心点,如果大于500未检测到,仍需要返回一些值
Нам нужно создать новое изображение в цикле while для вызова функции getContours().
while True:
success, img = cap.read()
imgResult = img.copy()
findColor(img, myColors)
cv2.imshow("Result", img)
if cv2.waitKey(1) & 0xFF == ord('q'):
Break
Теперь мы можем проверить, правильно ли выполнена печать, в функции findColor нам нужно найти контуры, поэтому нам нужно вызвать функцию getContours в функции findColor с параметром, установленным в маску.
def findColor(img, myColors): # 查找颜色函数
imgHSV = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
for color in myColors:
lower = np.array(color[0:3])
upper = np.array(color[3:6])
mask = cv2.inRange(imgHSV, lower, upper)
getContours(mask)
# cv2.imshow(str(color[0]), mask)
Запустите программу для проверкиТак что тест не даст никакого эффекта, нам нужно найти ошибку
Ошибка в том, что в финальном выводе цикла while мы выводим не скопированное новое изображение imgResult, а img, и img, потому что cv2.imshow(str(color[0]), mask) Deleted и не может быть отображен. Поэтому нам нужно изменить img на imgResult, а затем запустить код для проверки.
Обнаружение красного контураОбнаружение синего контура
Обнаружение зеленого контура
Нам нужна ограничительная рамка вокруг цвета, теперь нам нужно отправить эти значения, центральную точку можно отправить, но мы хотим рисовать от кончика пера, а не от центра обнаруженного объекта, поэтому мы отправим центр. Поэтому нам нужно вернуть x+w//2 и значение y, что даст нам самую высокую точку острия и его центр. Для некоторых непредвиденных ситуаций, таких как площадь не больше 500, нам также нужно вернуть некоторые значения, поэтому нам нужно присвоить начальные значения x, y, w и h равными 0.
def getContours(img): # chapter8
contours, hierarchy = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) # chapter8
x, y, w, h = 0, 0, 0, 0
for cnt in contours:
area = cv2.contourArea(cnt)[]
if area > 500:
cv2.drawContours(imgResult, cnt, -1, (255, 0, 0), 3)
peri = cv2.arcLength(cnt, True)
approx = cv2.approxPolyDP(cnt, 0.02 * peri, True) # chapter8
x, y, w, h = cv2.boundingRect(approx) # chapter8
return x + w // 2, y
Нам нужно получить функции x, y в функции findColor, поэтому мы присваиваем значение точки, полученное с помощью getContours(mask), значениям x и y. Значения x и y эквивалентны центру круга, поэтому мы можем начать рисовать круг, мы рисуем его на полученном изображении imgResult, центральная точка — это x и y, а затем мы устанавливаем радиус равным 8, поэтому круг не слишком большой, просто отлично. В качестве базовой единицы для рисования пути. Затем сначала настройте цвет и используйте cv2.FILLED, чтобы заполнить цвет внутри точки. Например, сначала мы установили цвет (255,0,0), используемый здесь цветовой режим — BGR, поэтому в результате мы должны увидеть сплошную синюю точку.
def findColor(img, myColors): # 查找颜色函数
imgHSV = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
for color in myColors:
lower = np.array(color[0:3])
upper = np.array(color[3:6])
mask = cv2.inRange(imgHSV, lower, upper)
x, y = getContours(mask)
cv2.circle(imgResult, (x, y), 8, (255, 0, 0), cv2.FILLED)
# cv2.imshow(str(color[0]), mask)
красныйсиний
зеленый
Результат теста успешно рисует точки тремя цветами.
Нам нужно обратить внимание на различие здесь, потому что точка, которую мы вводим, является центром верхней части изображения, поэтому, когда угол нашего изображения не слишком наклонен, наша точка будет на объекте, а когда она наклонена, точка точка будет вне объекта.
Без наклона:При наклоне:
Обращение к этому моменту сложно на данный момент, поэтому мы не будем вдаваться в подробности, давайте пока просто будем говорить прямо. Что нужно изменить сейчас, так это то, что цвет точек, которые мне нужно отобразить, должен быть не нашим пользовательским цветом, а цветом самого объекта.
Теперь, когда контур определен правильно, он нам больше не нужен, поэтому мы можем сначала удалить его.
def getContours(img): # chapter8
contours, hierarchy = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) # chapter8
x, y, w, h = 0, 0, 0, 0
for cnt in contours:
area = cv2.contourArea(cnt)
if area > 500:
#cv2.drawContours(imgResult, cnt, -1, (255, 0, 0), 3)
peri = cv2.arcLength(cnt, True)
approx = cv2.approxPolyDP(cnt, 0.02 * peri, True) # chapter8
x, y, w, h = cv2.boundingRect(approx) # chapter8
return x + w // 2, y
Нам нужно изменить цвет, поэтому нам нужно определить значение цвета, например, обнаружен красный цвет, какого цвета он должен быть на графике, поэтому мы назовем его myColorValues, также нам нужно создать список в myColorValues, в этом список, нам нужно определить все желаемые цвета. Здесь у нас пока три цвета, поэтому мы определяем три значения списка. Мы можем преобразовать в соответствии с соответствующим значением оттенка и насыщенности, и преобразованный веб-сайтwoohoo.rapid table.com/Web/color/R…красныйсиний
зеленый
Затем мы записываем цвет в список myColorValues, используя режим BGR.
myColorValues = [[0, 0, 255], # 红色
[255, 0, 0], # 蓝色
[0, 255, 0]] # 绿色
Теперь это наши цвета, и что мы можем сделать, так это нарисовать сплошные круги на основе этих цветовых значений. В качестве входных данных нам нужно значение myColorValues. Поэтому вам нужно использовать myColorValues в качестве входного параметра findColor, а myColorValues — в качестве входного параметра findColor в цикле while.
В функции findColor нам нужен счетчик, чтобы фактически считать, сколько раз, поэтому мы определяем переменную count и присваиваем ее начальное значение 0. В цикле for findColor при каждом рисовании круга счетчик увеличивается на единицу. При рисовании круга нам нужно изменить исходное предустановленное значение цвета на значение myColorValues и изменить исходное (255, 0, 0) на myColorValues[count], чтобы мы могли получить значение BGR нужного цвета. обнаруживаться каждый раз.
Запустите программу для проверки.
красныйсиний
зеленый
5.4 Реализовать дизайн траектории рисования
Теперь у нас есть правильные цвета и правильные значения, все, что нам нужно сделать, это нарисовать точки, чтобы нарисовать ход движения. Мы собираемся создать список точек, затем мы будем показывать его каждый раз, перебирая его, поэтому вверху сначала создайте список с именем myPoints, первое значение должно быть x, второе должно быть y, а третий должен быть colorid.
myPoints = [] ## [x , y , colorId ]
Нам нужно создать функцию, которая зацикливает список myPoints, проверяет значения x, y и рисует. Что мы можем сделать, так это создать новую функцию с именем drawOnCanvas, которая принимает значения myPoints и myColorValues, переданные в параметрах. В цикле for используйте переменную point для обхода списка myPoints, затем поместите оператор рисования круга, написанный в findColor, в цикл for, замените исходный x на point[0] и замените исходный y на point[1] , замените count на point[2]. Нам нужно присвоить значение findColor для newPoints в цикле while.
while True:
success, img = cap.read()
imgResult = img.copy()
newPoints = findColor(img, myColors, myColorValues)
cv2.imshow("Result", imgResult)
if cv2.waitKey(1) & 0xFF == ord('q'):
Break
Итак, когда мы определяем цвет, нам нужно вернуть значение точки в функции findColor.Если значение x, y не обнаружено, то x, y не нужно возвращать, просто нужно добавить. Перед подсчетом количества мы можем добавить оператор суждения.Если x и y не равны 0, то нам нужно использовать только добавление для добавления.Здесь нам нужна новая переменная списка newPoints, где каждый элемент имеет x, y и количество трех ценности. Каждый раз, когда x и y не равны 0, добавляется каждая идентифицированная точка, которая реализуется с помощью newPoints.append([x, y, count]), и каждая точка соединяется в линию, но эта линия не непрерывно, и будут некоторые пустые точки, которые необходимо оптимизировать ниже. Точно так же нам не хватает инициализации переменной списка newPoints, поэтому при инициализации переменной count я также инициализирую newPoints, и каждый цикл будет определять новую точку, поэтому каждый раз точка будет меняться, поэтому при инициализации список newPoints A определяется как пустой список. Наконец, мы можем вернуть значение списка newPoints.
def findColor(img, myColors, myColorValues): # 查找颜色函数
imgHSV = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
count = 0
newPoints = []
for color in myColors:
lower = np.array(color[0:3])
upper = np.array(color[3:6])
mask = cv2.inRange(imgHSV, lower, upper)
x, y = getContours(mask)
cv2.circle(imgResult, (x, y), 8, myColorValues[count], cv2.FILLED)
if x != 0 and y != 0:
newPoints.append([x, y, count])
count += 1
# cv2.imshow(str(color[0]), mask)
return newPoints
Таким образом, каждый раз, когда мы добавляем эти точки, как только мы отправляем эти новые точки в переменную newPoints цикла while. Мы можем проверить, действительно ли существует newPoints. Судя по тому, равна ли длина newPoints 0. Если он не равен 0, мы можем использовать цикл for и вместе добавить его в newPoints.
while True:
success, img = cap.read()
imgResult = img.copy()
newPoints = findColor(img, myColors, myColorValues)
if len(newPoints)!=0:
for newP in newPoints:
myPoints.append(newP)
cv2.imshow("Result", imgResult)
if cv2.waitKey(1) & 0xFF == ord('q'):
Break
Причина использования здесь цикла for заключается в том, что мы возвращаем переменную списка в функции findColor, поэтому мы не можем поместить список в список. Я получаю список, но мне нужны баллы, а не списки. Нам нужно разложить список на точки, поэтому их нужно добавить позже. Если длина newPoints не равна 0, то нам нужно нарисовать их, чтобы рисовать на холсте. Здесь мы вызываем функцию drawOnCanvas для вызова и передаем два параметра: myPoints и myColorValues.
while True:
success, img = cap.read()
imgResult = img.copy()
newPoints = findColor(img, myColors, myColorValues)
if len(newPoints) != 0:
for newP in newPoints:
myPoints.append(newP)
if len(myPoints) != 0:
drawOnCanvas(myPoints, myColorValues)
cv2.imshow("Result", imgResult)
if cv2.waitKey(1) & 0xFF == ord('q'):
Break
6. Отладка и анализ системы
В этом отчете тестирование кода и анализ двух модулей камеры, считывающих кадр изображения, приобретающих цвет и точку базовой единицы, выполняются в детальном проекте вместе с функцией тестирования отладки модуля классификации. В настоящее время написание модуля пути рисования завершено, что означает успешное написание всего проекта, поэтому давайте отладим весь проект.
Запустите код для отладки. Когда перед камерой появляются три цвета, должны быть точки соответствующих цветов.Когда объект движется, соответствующие точки будут соединены в линию, показывая линию, чтобы реализовать космический рисунок.
тест в одиночку
красныйсиний
зеленый
собрать для проверки
6.1 Запуск процесса
Мы используем Pycharm для кодирования и отладки, нажимаем кнопку запуска, а затем рисуем изображение.
6.2 Проблемы, возникающие при отладке системы
(1) При выполнении контурного рисования мы не выводим скопированное новое изображение imgResult, а выводим img и img, потому что мы удаляем cv2.imshow(str(color[0]), mask) и не можем отображаться. Вам нужно изменить img на imgResult в цикле while, а затем запустить код для проверки. Результаты выглядят так, как ожидалось. (2) При рисовании точек нам нужно обратить внимание на различие здесь, потому что точка, которую мы вводим, является центром верхней части изображения, поэтому, когда угол нашего изображения не слишком наклонен, наша точка будет на объекте. При наклоне точка будет находиться за пределами объекта. Обращение к этому моменту сложно на данный момент, поэтому мы не будем вдаваться в подробности, давайте пока просто будем говорить прямо. Что нужно изменить сейчас, так это то, что цвет точек, которые мне нужно отобразить, должен быть не нашим пользовательским цветом, а цветом самого объекта. (3) В приведенном выше тесте и окончательном выводе изображения все изображения, которые мы получаем, являются положительными, что противоположно текущему направлению наших действий, что не способствует рисованию пространства пользователем. Следовательно, нам нужно отразить все окно, полученное в конце. Конкретный код выглядит следующим образом.
if success == True: # 用来实现输出的水平翻转
new_img = cv2.flip(imgResult, 180)
После того, как камера подтвердит, что чтение прошло успешно, imgResult переворачивается по горизонтали на 180 градусов, а затем изображению присваивается новое значение с именем new_img, и, наконец, результат отображения imshow также выводится с помощью new_img.
После решения этой задачи мы заодно решили другую задачу, то есть рисование линий не очень непрерывное, просто набор простых точек. Это как-то связано с тем, что изображение не зеркальное. Линии также становятся непрерывными после зеркального отражения нового изображения.
Ниже приведен тестовый эффект
красныйсиний
зеленый
7. Инструкции для пользователя
Во-первых, нам нужно найти кнопку запуска в Pycharm, которая расположена вверху справа и представляет собой зеленый треугольник.
Щелкните зеленый треугольник, чтобы запустить программу. Подождите некоторое время, ниже появится окно выбора камеры, нажмите на поле выбора, чтобы нарисовать в поле выбора.
В соответствии с зеркальным изображением вы можете напрямую рисовать и использовать разные цвета для рисования трех фигур RGB.Наконец, для выхода нажмите Q. Если это режим ввода на китайском языке, переключитесь на английский режим, чтобы выйти.
8. Результаты испытаний
В тесте мы обнаружили, что поскольку цвет руки относительно близок к оранжевому, то при распознавании цвет руки может быть распознан как красный, в результате чего красный цвет появляется там, где его быть не должно. Проблема здесь нуждается в соответствующей оптимизации в модуле распознавания цвета. Или можно добавить новые функции для оптимизации точности распознавания. Кроме того, в процессе работы, когда цветные объекты попадают в окно в начале, будут точки, которые нельзя сразу распознать и соединить в линию, мы считаем, что этот момент также нуждается в последующей оптимизации. В этом отчете может быть реализован простой пространственный рисунок.
9. Резюме
Python — это объектно-ориентированный буквальный язык программирования. Мы считаем, что Python отличается исключительной гибкостью в работе со строками, прямыми отступами и простым синтаксисом. Подобно C, Python выполняется последовательно, в отличие от визуального C+, который запускается разными модулями по событию. Операция аналогична матлабу, есть окно редактирования и работающее окно (интерактивный интерпретатор), которое можно запустить после написания, а можно выполнить поочередно в режиме командной строки. После эксперимента я изучил основы Python, получил предварительное представление об основном синтаксисе и знаниях Python и смог скомпилировать хороший работающий модуль. Эксперименты с Python придали мне уверенности в завтрашнем дне работы и улучшили нашу способность выполнять настоящую работу. Мы считаем, что для изучения Opencv всегда лучше всего читать официальные документы, а затем проводить множество экспериментальных тестов с открытым исходным кодом, из которых можно узнать об использовании и принципе определенной функции или алгоритма, что очень важно. для начинающих. Благодаря многократному чтению официальных документов мы понимаем, какую функцию нужно использовать и как ее вызывать, а затем комбинируем несколько примеров для написания кода. Хотя в процессе возникают некоторые проблемы, которые не могут быть решены какое-то время, но они также решаются активным поиском решений.В целом, этот курс имеет большое значение.
10. Ссылки
[1]python.jobbole.com/Базовый обучающий сайт Python.
[2]www.w3cschool.cn/opencv/Официальная документация Opencv.
[3]GitHub.com/Поэзия Ланьсяо/…Пример алгоритма обработки изображений с открытым исходным кодом.
[4]GitHub.com/ASAbeneh/30…Учебный проект с открытым исходным кодом Python.
[5] Лю Жуйчжэнь, Ю Шици Учебное пособие по OpenCV — Основы [M] Пекин: Пекинский университет аэронавтики и астронавтики, 2007.
[6] Г. Брадски, Библиотека OpenCV[M], ResearchGate:CiNii, 2000.
[7] Чжан Цзивэнь, Фонд программирования на C++, [M], Пекин: Higher Education Press, 2003.
[8] Хоу Цзюньцзе, MFC [M], Ухань: Huazhong University of Science and Technology Press, 2001.
[9] Цифровая обработка изображений Гонсалеса (второе издание) [M], Пекин: Electronic Industry Press, 2005.
[10] Перевод Ю Шици, Learning OpenCV (китайская версия) [M], Пекин: Издательство Университета Цинхуа, 2009.