Как-то один школьник, назовём его Лёша (персональные данные наше всё) решил освоить 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 — это набор стандартов деятельности компании, которые социально сознательные инвесторы используют для проверки потенциальных инвестиций. Экологические критерии определяют, как компания выступает в роли хранителя природы. Социальные критерии исследуют, как она управляет отношениями с сотрудниками, поставщиками, клиентами и обществом. Корпоративное управление касается руководства компанией, оплаты труда руководителей, аудита, внутреннего контроля и прав акционеров

Комментарии (0)