Как-то один школьник, назовём его Лёша (персональные данные наше всё) решил освоить Computer Vision (далее CV). В качестве практической задачи он решил, что подойдёт задача поиска по контуру и определения дерева. Картинок разных деревьев он в прошлом году скачал много, когда готовил выступление по ESG. В прошлом году учитель на уроке «внеклассного» английского, рассказывал про направление Environmental, Social, and Corporate Governance[1]. Потом каждый брал себе тему доклада перед классом, Лёша рассказывал, сколько кислорода какое дерево производит, полезно, при выборе чем озеленять территорию предприятия.
ИТАК, объектов поиска хватает (ЧТО искать), а картинок для поиска (ГДЕ искать) он наделал из тех же картинок, для иллюстрации в том же докладе (много деревьев из одного изображения). Примеры:
Объект поиска(ЧТО)
Место поиска (ГДЕ)
Загрузить данные конечно легко, код загрузки исполнил и подождал пока не нажата клавиша, что бы разглядеть картинку:
import cv2 # импорт библиотеки
input_file = 'C:\\Temp\\t\\CV_ML\\KlenKr_Cl_WHT.png' # input_file – имя файла
image = cv2.imread(input_file) # загрузить картинку
cv2.imshow("Image", image) # показать картинку
cv2.waitKey(0) # ждать пока не нажата любая клавиша
cv2.destroyAllWindows() # закрыть окно показа картинки
НО, возник первый вопрос — это же цветные картинки, ГДЕ искать, да ещё и объекты (ЧТО), тоже цветные. Как в них контуры строить? Решил Лёша перевести всё в серое и посмотреть, как оно будет выглядеть.
Код преобразования картинки в градации серого:
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # картинку цвет по умолчанию в серое
cv2.imshow("Image", gray) # показать картинку
cv2.waitKey(0) # ждать пока не нажата любая клавиша
cv2.destroyAllWindows() # закрыть окно показа картинки
Объект (серое)
Место поиска (серое)
Понятней, чем в цвете!
А если сделать картинки вообще в Ч/Б?
Объект (Ч/Б)
Место поиска (Ч/Б)
Нарисовал спектр для картинки с распределением по количеству точек для серой яркости:
Код как всегда в python прост:
# Строим grayscale гистограмму
hist = cv2.calcHist([gray],[0],None,[256],[0,256])
# Нарисовать
plt.plot(hist)
plt.xlim([0,256])
plt.show()
Спектр серого для картинки ЧТО, по горизонтальной оси отражена яркость от 0 (чёрное) до 255 (белое), по вертикальной оси – количество точек на картинке этой яркости.
Спектр серого для картинки ГДЕ, аналогично по горизонтальной оси отражена яркость от 0 (чёрное) до 255 (белое), по вертикальной оси – количество точек на картинке этой яркости.
Лёша посмотрел разные картинки и везде увидел одно и тоже общее правило, можно срезать часть спектра, точек слева и справа в спектре, остальное пересчитать, и картинка станет контрастнее, а потом уже переводить её в Ч/Б изображение.
Он построил обе гистограммы исходного спектра и спектра с изменённой яркостью для картинок ЧТО и ГДЕ, для удобства отразив на гистограмме оранжевым цветом изменённый спектр.
Спектр серого для картинки ЧТО, по горизонтальной оси - яркость от 0 (чёрное) до 255 (белое), по вертикальной оси – количество точек на картинке для этой яркости.
Спектр серого для картинки ГДЕ по горизонтальной оси - яркость от 0 (чёрное) до 255 (белое), по вертикальной оси – количество точек на картинке для этой яркости.
-спектр улучш. объект (серое)
улучш. место поиска (серое)
-спектр улучш. объект (Ч/Б)
улучш. место поиска (Ч/Б)
Код срезания спектра с двух сторон (процент срезания=25)
def auto_bght_and_show(image, clip_hist_percent=25):
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# Строим grayscale гистограмму
hist = cv2.calcHist([gray],[0],None,[256],[0,256])
hist_size = len(hist)
# Вычисляем кумулятивное распределение из гистограммы
accumulator = []
accumulator.append(float(hist[0]))
for index in range(1, hist_size):
accumulator.append(accumulator[index -1] + float(hist[index]))
# Определяем точку для разреза
maximum = accumulator[-1]
clip_hist_percent *= (maximum/100.0)
clip_hist_percent /= 2.0
# Вычисляем левую границу обрезки
minimum_gray = 0
while accumulator[minimum_gray] < clip_hist_percent:
minimum_gray += 1
# Вычисляем правую границу обрезки
maximum_gray = hist_size -1
while accumulator[maximum_gray] >= (maximum - clip_hist_percent):
maximum_gray -= 1
# Вычисляем alpha и beta переменные коррекции
alpha = 255 / (maximum_gray - minimum_gray)
beta = -minimum_gray * alpha
print('alpha=',alpha,'beta=',beta)
auto_result = cv2.convertScaleAbs(gray, alpha=alpha, beta=beta)
return auto_result
Лёша довольный своей работой пошёл спать. Завтра он займётся распознаванием.
<![endif]>
[1] ESG — это набор стандартов деятельности компании, которые социально сознательные инвесторы используют для проверки потенциальных инвестиций. Экологические критерии определяют, как компания выступает в роли хранителя природы. Социальные критерии исследуют, как она управляет отношениями с сотрудниками, поставщиками, клиентами и обществом. Корпоративное управление касается руководства компанией, оплаты труда руководителей, аудита, внутреннего контроля и прав акционеров