Увидев в Интернете связанные статьи о python для распознавания изображений, я действительно чувствую, что функция python слишком мощная, поэтому я суммирую эти статьи и создаю свою собственную систему знаний. Конечно, тему распознавания изображений, как отрасли компьютерных наук, невозможно объяснить всего в нескольких предложениях в этой статье, поэтому данная статья представляет собой лишь научно-популярную направленность основных алгоритмов. Я видел блог, в котором это было представлено, но он использовал реализацию Image в PIL, что было проблематично, поэтому он использовал библиотеку Opencv для более лаконичной реализации.
Связанный фон
Чтобы идентифицировать два похожих изображения, о каком процессе восприятия идет речь? Прежде всего, мы будем различать типы этих двух фотографий, например, пейзажные фотографии или портретные фотографии. На пейзажной фотографии это пустыня или океан, а на портретной фотографии два человека с лицами китайских иероглифов или с лицами дынных семечек (или с перевернутыми лицами дынных семечек... ха-ха...).
Так что с точки зрения машины это одно и то же, сначала определите характеристики изображения, а потом сравните.
Очевидно, что без обученного компьютера (т. е. построения модели) компьютеру трудно отличить океан от пустыни. Но компьютер может легко распознать значение пикселя изображения.
Поэтому при распознавании изображений чаще всего используются цветовые признаки. (Другие часто используемые функции включают функции текстуры, функции формы, функции пространственного отношения и т. д.)
который делится на
Гистограмма набор цветов цветной момент Совокупный вектор График корреляции
Метод расчета гистограммы
Вот краткое описание гистограммы.
Сначала позаимствуйте изображение Бабочки Цветка Любви,
[Ошибка загрузки изображения...(image-6ca66e-1617780875489)]
Невооруженным глазом эти две картинки похожи примерно на 80%. В Python метод calcHist() в opencv используется для получения данных гистограммы.Возвращенный результат представляет собой список.С помощью matplotlib рисуются данные гистограммы этих двух графиков. следующее:
Да, мы ясно видим, что гистограммы двух изображений все еще относительно совпадают. Поэтому метод использования гистограммы для определения сходства двух изображений заключается в вычислении степени совпадения их гистограмм. Метод расчета следующий:
где gi и si относятся к i-й точке двух кривых соответственно.
Конечным результатом расчета является подобие.
Однако у этого метода есть очевидная слабость, то есть он смотрит на глобальное распределение цветов и не может описать локальное распределение цветов и расположение цветов.
То есть, если одна картинка в основном голубая, содержание — голубое небо, а другая картинка тоже в основном голубая, но содержание в том, что девушка одета в синюю юбку, то алгоритм, скорее всего, подумает, что эти две картинки подобных.
Один из способов смягчить эту слабость — использовать метод кадрирования изображения, чтобы разделить изображения на равные части, затем вычислить их сходство по отдельности и, наконец, рассмотреть их всесторонне.
Отпечаток изображения и расстояние Хэмминга
Перед введением следующих других методов оценки сходства сначала добавляются некоторые понятия. Первый — изображение отпечатка пальца
Подобно отпечаткам пальцев человека, отпечатки пальцев изображений являются символом идентичности, а отпечатки пальцев изображений представляют собой просто набор двоичных чисел, полученных путем обработки изображения в соответствии с определенным алгоритмом хеширования.
Кстати, можно ввести понятие расстояния Хэмминга.
Если один набор двоичных данных равен 101, а другой набор равен 111, то, очевидно, изменение вторых данных 0 первого набора на 1 может стать вторым набором данных 111, поэтому расстояние Хэмминга двух наборов данных равно 1.
Проще говоря, расстояние Хэмминга — это количество шагов, необходимых для преобразования набора двоичных данных в другой набор данных. Очевидно, что это значение может измерять разницу между двумя изображениями. Чем меньше расстояние Хэмминга, тем выше сходство. Расстояние Хэмминга равно 0, что означает, что две картинки абсолютно одинаковы.
Как рассчитать расстояние Хэмминга, см. следующие три алгоритма хеширования.
Среднее хеширование (aHash)
Этот алгоритм основан на сравнении каждого пикселя изображения в градациях серого со средним значением
Общие шаги:
- 1. Масштабируйте изображение, общий размер 8*8, 64 пикселя.
- 2. Преобразовать в оттенки серого
- 3. Рассчитайте среднее значение. Рассчитайте среднее значение всех пикселей изображения после обработки в градациях серого, которое можно рассчитать непосредственно с помощью метода mean() в numpy.
- 4. Сравните значение серого пикселя: пройдитесь по каждому пикселю серого изображения, если оно больше среднего значения, оно записывается как 1, в противном случае — 0.
- 5. Получите информационный отпечаток: объедините 64 бита, и порядок будет случайным, чтобы сохранить согласованность.
Наконец, сравните отпечатки двух изображений, чтобы получить расстояние Хэмминга.
Алгоритм перцептивного хеширования (pHash)
Алгоритм среднего хеширования слишком строг и недостаточно точен и больше подходит для поиска по миниатюрам.Для получения более точных результатов можно выбрать перцепционный алгоритм хеширования, использующий метод ДКП (дискретное косинусное преобразование) для уменьшения частоты
Общие шаги:
- Уменьшите изображение: 32*32 — хороший размер, который удобен для расчета DCT.
- Преобразовать в оттенки серого
- Вычислить DCT: используйте метод dct(), предоставленный в Opencv, обратите внимание, что входное изображение должно быть 32-битным типом с плавающей запятой, поэтому сначала используйте float32 в numpy для преобразования
- Уменьшенное DCT: матрица после расчета DCT составляет 32 * 32, сохраняя 8 * 8 в верхнем левом углу, они представляют самую низкую частоту изображения.
- Вычислить среднее значение: вычислить среднее значение всех пикселей после уменьшения DCT.
- Для дальнейшего уменьшения ДКП: если оно больше среднего значения, оно будет записано как 1, иначе оно будет записано как 0.
- Получите информационный отпечаток: объедините 64 информационных бита, и порядок будет случайным для обеспечения согласованности.
Наконец, сравните отпечатки двух изображений, чтобы получить расстояние Хэмминга.
Алгоритм dHash
По сравнению с pHash, dHash намного быстрее, и по сравнению с aHash, dHash работает лучше с почти такой же эффективностью, он реализован на основе градиентов.
шаг:
- Уменьшить изображение: уменьшить до 9 * 8, чтобы оно имело 72 пикселя.
- Преобразовать в оттенки серого
- Вычислите значение разницы: алгоритм dHash работает между соседними пикселями, так что 8 разных различий генерируются между 9 пикселями в каждой строке, всего 8 строк и 64 значения разницы.
- Получите отпечаток пальца: если пиксель слева ярче, чем справа, запишите 1, иначе 0.
- Наконец, сравните отпечатки двух изображений, чтобы получить расстояние Хэмминга.
Весь код реализован следующим образом:
# -*- coding: utf-8 -*-
# 利用python实现多种方法来实现图像识别
import cv2
import numpy as np
from matplotlib import pyplot as plt
# 最简单的以灰度直方图作为相似比较的实现
def classify_gray_hist(image1,image2,size = (256,256)):
# 先计算直方图
# 几个参数必须用方括号括起来
# 这里直接用灰度图计算直方图,所以是使用第一个通道,
# 也可以进行通道分离后,得到多个通道的直方图
# bins 取为16
image1 = cv2.resize(image1,size)
image2 = cv2.resize(image2,size)
hist1 = cv2.calcHist([image1],[0],None,[256],[0.0,255.0])
hist2 = cv2.calcHist([image2],[0],None,[256],[0.0,255.0])
# 可以比较下直方图
plt.plot(range(256),hist1,'r')
plt.plot(range(256),hist2,'b')
plt.show()
# 计算直方图的重合度
degree = 0
for i in range(len(hist1)):
if hist1[i] != hist2[i]:
degree = degree + (1 - abs(hist1[i]-hist2[i])/max(hist1[i],hist2[i]))
else:
degree = degree + 1
degree = degree/len(hist1)
return degree
# 计算单通道的直方图的相似值
def calculate(image1,image2):
hist1 = cv2.calcHist([image1],[0],None,[256],[0.0,255.0])
hist2 = cv2.calcHist([image2],[0],None,[256],[0.0,255.0])
# 计算直方图的重合度
degree = 0
for i in range(len(hist1)):
if hist1[i] != hist2[i]:
degree = degree + (1 - abs(hist1[i]-hist2[i])/max(hist1[i],hist2[i]))
else:
degree = degree + 1
degree = degree/len(hist1)
return degree
# 通过得到每个通道的直方图来计算相似度
def classify_hist_with_split(image1,image2,size = (256,256)):
# 将图像resize后,分离为三个通道,再计算每个通道的相似值
image1 = cv2.resize(image1,size)
image2 = cv2.resize(image2,size)
sub_image1 = cv2.split(image1)
sub_image2 = cv2.split(image2)
sub_data = 0
for im1,im2 in zip(sub_image1,sub_image2):
sub_data += calculate(im1,im2)
sub_data = sub_data/3
return sub_data
# 平均哈希算法计算
def classify_aHash(image1,image2):
image1 = cv2.resize(image1,(8,8))
image2 = cv2.resize(image2,(8,8))
gray1 = cv2.cvtColor(image1,cv2.COLOR_BGR2GRAY)
gray2 = cv2.cvtColor(image2,cv2.COLOR_BGR2GRAY)
hash1 = getHash(gray1)
hash2 = getHash(gray2)
return Hamming_distance(hash1,hash2)
def classify_pHash(image1,image2):
image1 = cv2.resize(image1,(32,32))
image2 = cv2.resize(image2,(32,32))
gray1 = cv2.cvtColor(image1,cv2.COLOR_BGR2GRAY)
gray2 = cv2.cvtColor(image2,cv2.COLOR_BGR2GRAY)
# 将灰度图转为浮点型,再进行dct变换
dct1 = cv2.dct(np.float32(gray1))
dct2 = cv2.dct(np.float32(gray2))
# 取左上角的8*8,这些代表图片的最低频率
# 这个操作等价于c++中利用opencv实现的掩码操作
# 在python中进行掩码操作,可以直接这样取出图像矩阵的某一部分
dct1_roi = dct1[0:8,0:8]
dct2_roi = dct2[0:8,0:8]
hash1 = getHash(dct1_roi)
hash2 = getHash(dct2_roi)
return Hamming_distance(hash1,hash2)
# 输入灰度图,返回hash
def getHash(image):
avreage = np.mean(image)
hash = []
for i in range(image.shape[0]):
for j in range(image.shape[1]):
if image[i,j] > avreage:
hash.append(1)
else:
hash.append(0)
return hash
# 计算汉明距离
def Hamming_distance(hash1,hash2):
num = 0
for index in range(len(hash1)):
if hash1[index] != hash2[index]:
num += 1
return num
if __name__ == '__main__':
img1 = cv2.imread('10.jpg')
cv2.imshow('img1',img1)
img2 = cv2.imread('11.jpg')
cv2.imshow('img2',img2)
degree = classify_gray_hist(img1,img2)
#degree = classify_hist_with_split(img1,img2)
#degree = classify_aHash(img1,img2)
#degree = classify_pHash(img1,img2)
print degree
cv2.waitKey(0)
портал ресурсов
-
Обратите внимание на паблик-аккаунт [==Будьте нежным программистом==]
-
Ответить на фоне публичного аккаунта [==Будь программистом тендеров==] [данные питона】【Осенний набор 2020] Вы можете получить соответствующий сюрприз!
-
Адрес блога, созданный мной:Блог Кошмара Назад
"❤️Спасибо всем"
- Поставьте лайк и поддержите его, чтобы больше людей увидело этот контент
- Вы можете поделиться со мной своими мыслями в области комментариев, и вы также можете записать свой мыслительный процесс в области комментариев.