Вы находитесь на странице: 1из 11

Федеральное государственное бюджетное образовательное учреждение высшего образования

БЕЛГОРОДСКИЙ ГОСУДАРСТВЕННЫЙ ТЕХНОЛОГИЧЕСКИЙ


УНИВЕРСИТЕТ ИМ. В. Г. ШУХОВА
(БГТУ ИМ. В. Г. ШУХОВА)

ИНСТИТУТ ЭНЕРГЕТИКИ, ИНФОРМАЦИОННЫХ ТЕХНОЛОГИЙ


И УПРАВЛЯЮЩИХ СИСТЕМ
Кафедра технической кибернетики

Системы технического зрения


Лабораторная работа № 1. Изучение методов первичной обработки изображений

Вариант № 2

Выполнил: Принял:
студент группы МР-41 доцент кафедры ТК
Шифр группы Должность

Баптишта Паулу канд. техн. наук


ФИО Ученая степень, звание

Кариков Е.Б.
Подпись Дата ФИО

Замечания: Отметка о защите:

Подпись Дата

Белгород 2020
Цель работы: изучить различные методы первичной обработки изображений
с помощью библиотеки scikit – image.

Задание 1
• Реализовать считывание изображения с жесткого диска;
• Реализовать преобразование изображения из RGB – формата в формат
HSV, YUV, Grayscale с выводом всех каналов;
• Обеспечить обнаружение кожи лица с помощью цветового
пространства HSV;
• Описать математические зависимости, лежащие в основе
рассмотренных цветовых моделей.
Выполнение:

Перевод из RGB в HSV осуществляется по следующим формулам:

G−B
60 × , if MAX(R, G B) = R and G ≥ B
MAX(R, G, B) − MIN(R, G, B)
G−B
60 × + 360, if MAX(R, G B) = R and G < B
MAX(R, G, B) − MIN(R, G, B)
H=
B−R
60 × + 120, if MAX(R, G B) = G
MAX(R, G, B) − MIN(R, G, B)
R−G
60 × + 240, if MAX(R, G B) = B
{ MAX(R, G, B) − MIN(R, G, B)
0, if MAX(R, G B) = 0
S={ MIN(R, G B)
1−
MAX(R, G B)
V = MAX(R, G B).

Перевод из RGB в YUV осуществляется по следующим формулам:


Y = K R R + (1 − K R − K B )G + K B B
U=B−Y
V = R − Y, где
K R и K B-коэффициенты, задаваемые различными стандартами, например
K R = 0.299, K B = 0.114.

Перевод из RGB в grayscale осуществляется по следующей формуле:


gray = K R R + K G G + K B B.

2
Результат работы программы представлен на рисунке 1.
RGB – формат

HSV – формат

YUV – формат

Рис.1. Изображение в различных форматах


3
Для обнаружения кожи лица необходимо задаться некоторым диапазоном
цветов. Искомые цвета должны быть телесными. В силу того, что поиск
производится в формате HSV необходимо перевести цвет из RGB формата в
формат HSV. Таким образом мы получим максимальные и минимальные значения
h (hue) и s (saturation). Далее отбираются значения, принадлежащие полученным
диапазонам. Таким образом, получив маску, можно получить изображение лица
человека. Результат работы программы изображен на рисунке 2.

Рис.2. Обнаружение кожи лица человека

Задание 2
• Реализовать фильтрацию шумов – гауссовский фильтр, медианный
фильтр;
• Найти контуры с помощью фильтра Собеля, Лапласа и Кенни;
• Проанализировать и сравнить качество определения границ;
• Описать математические зависимости, лежащие в основе
рассмотренных методов фильтрации.
В система технического зрения существует понятие ядра. В случае
гауссовского фильтра элементы ядра распределены по нормальному закону, т.е.
наибольшая величина находится в центре, а наименьшая по углам ядра. Наиболее
часто используют ядра размером 3х3 и 5х5. Например:
0,5 0,75 0,5
0,75 1,0 0,75
0,5 0,75 0,5
Ядро проходит над изображением и соответствующие величины
перемножаются, что представляет собой операцию свертки.

4
В медианном фильтре значения внутри окна фильтра сортируются по
возрастанию или убыванию, а значение, находящееся в середине полученного
списка, поступает на выход фильтра.
Результат работы программы представлен на рисунке 3.

Гауссовский Фильтр:

Медианный Фильтр:

Рис.3. Фильтрация шумов фильтром гаусса и медианным фильтром


Для нахождения контуров также используются ядра. Будем использовать
распространенный формат 3х3.
В фильтре Собеля используются ядра, с которыми сворачивают исходное
изображение для вычисления приближенных значений производных по
горизонтали и вертикали.
 −1 −2 −1  −1 0 1 
Gx =  0 0 0  * A; G y =  −2 0 2  * A.
 1 2 1   −1 0 1 

5
где Gx, Gy – два изображения, на которых каждая точка содержит
приближенные производные по x и y, А – исходное изображение,* - двумерная
операция свертки.
Тогда приближенное значение величины градиента:
G = Gx 2 + G y 2 .
В фильтре Лапласа используется ядро в виде:
0 1 0 
L = 1 −4 1  .
0 1 0 
Фильтрация Кенни состоит из нескольких этапов:
1. Сглаживание. Оператор Кенни использует фильтр, который может быть
хорошо приближен к первой производной гауссианы, 𝜎 = 1,4.
2 4 5 4 2
 4 9 12 9 4 
1  
B=  5 12 15 12 5  * A.
159  
 4 9 12 9 4 
 2 4 5 4 2 

2. Поиск градиентов. Границы отмечаются там, где градиент изображения


приобретает максимальное значение. Они могут иметь различное
направление, поэтому алгоритм Кенни использует четыре фильтра для
обнаружения горизонтальных, вертикальных и диагональных ребер в
размытом изображении.
G = Gx 2 + G y 2 .
3. Подавление немаксимумов. Только локальные максимумы отмечаются как
границы.
4. Двойная пороговая фильтрация. Потенциальные границы определяются
порогами.
5. Трассировка области неоднозначности. Итоговые границы определяются
путём подавления всех краёв, не связанных с определенными (сильными)
границами.

Результат работы программы представлен на рисунке 3,4.

6
Рис3:Фильтр Лапласа:

Рис.4. Поиск контуров фильтрами Собеля, Лапласа и Кенни

7
Приложения: 1
Код программы на языке Python
import cv2
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image, ImageFilter
from scipy.ndimage import gaussian_filter
from scipy import signal
from skimage.morphology import reconstruction, disk
from skimage.filters import rank, roberts, sobel, laplace
from skimage import feature, data, filters
from skimage import img_as_float
from skimage import feature,data
from skimage import io, color, img_as_float
from skimage.util import random_noise
from skimage.filters import gaussian, median
from skimage.restoration import (denoise_tv_chambolle, denoise_bilateral,
denoise_wavelet, estimate_sigma)

def show_image(img_arr, title_arr, x, y, ncols=0, nrows=0, color=False):


if nrows > 0:
fig, axes = plt.subplots(ncols=ncols, nrows=nrows, figsize=(x, y),
sharex=True, sharey=True)
else:
fig, axes = plt.subplots(ncols=ncols, figsize=(x, y))

ax = axes.ravel()

for i in range(0, len(img_arr)):


if color:
ax[i].imshow(img_arr[i], cmap=color[i])
else:
ax[i].imshow(img_arr[i], cmap=plt.cm.gray)
ax[i].set_title(title_arr[i])
ax[i].axis('off')

# считывание
img = io.imread('photo3.jfif')
try:
img_rgb = color.rgba2rgb(img)
except:
img_rgb = img

#РЕАЛИЗАЦИИ ПРЕОБРАЗОВАНИЯ ИЗОБРАЖЕНИЯ В РАЗЛИЧНЫЕ ФОРМАТЫ


def rgb_to_hsv(img): #перевод из rgb в hsv
hsv = img.copy()*0
for x in range (img.shape[1]-1):
for y in range (img.shape[0]-1):
pixel = img[y,x]/255
mx = max(pixel)
mn = min(pixel)
df = mx-mn
if mx == mn:
h = 0
elif mx == pixel[0]: #pixel[0]=r
h = (60 * ((pixel[1]-pixel[2])/df) + 360) % 360
elif mx == pixel[1]: #pixel[1]=g
h = (60 * ((pixel[2]-pixel[0])/df) + 120) % 360
elif mx == pixel[2]: #pixel[2]=b
h = (60 * ((pixel[0]-pixel[1])/df) + 240) % 360
if mx == 0:
s = 0
else:
8
s = (df/mx)*100
v = mx * 100
hsv[y,x,0] = h
hsv[y,x,1] = s
hsv[y,x,2] = v
return hsv #полученные значения h, s, v из rgb

# преобразования
img_hsv = rgb_to_hsv(img_rgb)
img_yuv = color.rgb2yuv(img_rgb)
img_grscl = color.rgb2gray(img_rgb)

# вывод RGB
img_arr = [img_rgb, img_rgb[:, :, 0], img_rgb[:, :, 1], img_rgb[:, :, 2]]
color_arr = [plt.cm.gray, plt.cm.Reds, plt.cm.Greens, plt.cm.Blues]
titles = ['RGB image', 'Red channel', 'Green channel', 'Blue channel']
show_image(img_arr, titles, 11, 6, 2, 2, color_arr)

# вывод HSV
img_arr = [img_hsv, img_hsv[:, :, 0], img_hsv[:, :, 1], img_hsv[:, :, 2]]
color_arr = [plt.cm.gray, plt.cm.hsv, plt.cm.hsv, plt.cm.hsv]
titles = ['HSV image', 'Hue channel', 'Saturation channel', 'Value channel']
show_image(img_arr, titles, 11, 6, 2, 2, color_arr)

# вывод YUV
img_arr = [img_yuv, img_yuv[:, :, 0], img_yuv[:, :, 1], img_yuv[:, :, 2]]
color_arr = [plt.cm.gray, plt.cm.hsv, plt.cm.hsv, plt.cm.hsv]
titles = ['YUV image', 'Y channel', 'U channel', 'V channel']
show_image(img_arr, titles, 11, 6, 2, 2, color_arr)

#ОБНАРУЖЕНИЯ ЦВЕТНЫХ ОБЪЕКТОВ


# Задание диапазона телесных цветов
h_min = 0.002
h_max = 0.09
s_min = 0.2
s_max = 0.45

rgb_img = io.imread('lilwayne.jpg')
hsv_img = color.rgb2hsv(rgb_img)
h, s = hsv_img[..., 0], hsv_img[..., 1]
# Отбор значений, входящий в диапазон
h_mask = np.logical_and(h > h_min, h < h_max)
s_mask = np.logical_and(s > s_min, s < s_max)
# Маска изображения только с искомым диапазоном цветов
mask = np.logical_not(np.logical_and(h_mask, s_mask))
# Наложение маски на исходное RGB изображение
filter_img = rgb_img.copy()
filter_img[mask] = 255

#Вывод результат Обнаружение кожи лица человека


plt.figure(figsize=(11,6))
plt.subplot(121), plt.imshow(cv2.cvtColor(rgb_img, 0)),plt.title('RGB')
plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(cv2.cvtColor(filter_img, 0)),plt.title('RGB Filter')
plt.xticks([]), plt.yticks([])

#ГАУССОВСКИЙ ФИЛЬТР, МЕДИАННЫЙ ФИЛЬТР;

image = cv2.imread('gauss.JPG') # reads the image


image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) # convert to HSV
figure_size = 9 # the dimension of the x and y axis of the kernal.

# The image will first be converted to grayscale


image2 = cv2.cvtColor(image, cv2.COLOR_HSV2BGR)

9
image2 = cv2.cvtColor(image2, cv2.COLOR_BGR2GRAY)

new_image = cv2.GaussianBlur(image, (figure_size, figure_size),0)


new_image_gauss = cv2.GaussianBlur(image2, (figure_size, figure_size),0)
new_image1 = cv2.medianBlur(image, figure_size)
new_image2 = cv2.medianBlur(image2, figure_size)

plt.figure(figsize=(11,6))
plt.subplot(121), plt.imshow(cv2.cvtColor(image,
cv2.COLOR_HSV2RGB)),plt.title('Original')
plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(cv2.cvtColor(new_image,
cv2.COLOR_HSV2RGB)),plt.title('Gaussian Filter')
plt.xticks([]), plt.yticks([])

plt.figure(figsize=(11,6))
plt.subplot(121), plt.imshow(image2, cmap='gray'),plt.title('Original')
plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(new_image_gauss, cmap='gray'),plt.title('Gaussian
Filter')
plt.xticks([]), plt.yticks([])

plt.figure(figsize=(11,6))
plt.subplot(121), plt.imshow(cv2.cvtColor(image,
cv2.COLOR_HSV2RGB)),plt.title('Original')
plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(cv2.cvtColor(new_image1,
cv2.COLOR_HSV2RGB)),plt.title('Median Filter')
plt.xticks([]), plt.yticks([])

plt.figure(figsize=(11,6))
plt.subplot(121), plt.imshow(image2, cmap='gray'),plt.title('Original')
plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(new_image2, cmap='gray'),plt.title('Median Filter')
plt.xticks([]), plt.yticks([])

image = io.imread("zebra.jpg")
image = color.rgb2gray(image)
(width, height) = np.shape(image)

Laplasian = np.array([[0, 1, 0], #3x3 ядро


[1, -4, 1],
[0, 1, 0]])
#Филтр Лапласа
def multiply_entire(image):
lap_img = np.zeros(image.shape)
for i in range(1,width-1):
for j in range(1,height-1):
image_entry = image[i-1:i+2, j-1:j+2]
value = np.sum(image_entry*Laplasian) #
lap_img[i, j] = value
return lap_img
lap_img = multiply_entire(image)

#Вывод Филтр Лапласа


plt.figure(figsize=(11,6))
plt.subplot(121), plt.imshow(image, cmap='gray'),plt.title('Original')
plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(lap_img, cmap='gray'),plt.title('laplas Filter')
plt.xticks([]), plt.yticks([])

img_sobel = filters.sobel(image)
img_canny = feature.canny(image)
img_laplace = filters.laplace(image)

10
fig, ax = plt.subplots(nrows=2, ncols=2, figsize=(11, 6))

ax[0, 0].imshow(image, cmap=plt.cm.gray)


ax[0, 0].axis('off')
ax[0, 0].set_title('Original')
ax[0, 1].imshow(img_sobel, cmap=plt.cm.gray)
ax[0, 1].axis('off')
ax[0, 1].set_title(r'Sobel')
ax[1, 0].imshow(img_laplace, cmap=plt.cm.gray)
ax[1, 0].axis('off')
ax[1, 0].set_title(r'Laplace')
ax[1, 1].imshow(img_canny, cmap=plt.cm.gray)
ax[1, 1].axis('off')
ax[1, 1].set_title('Canny')

plt.tight_layout()
plt.show()

11