Python使用imagehash庫(kù)生成ahash算法的示例代碼
知識(shí)點(diǎn)補(bǔ)充
aHash算法
Hash算法進(jìn)行圖片相似度識(shí)別的本質(zhì),就是將圖片進(jìn)行Hash轉(zhuǎn)化,生成一組二進(jìn)制數(shù)字,然后通過(guò)比較不同圖片的Hash值距離找出相似圖片。aHash中文叫平均哈希算法,顧名思義,在進(jìn)行轉(zhuǎn)化過(guò)程中將用到像素均值。
基本原理:
1、縮小尺寸。這樣做會(huì)去除圖片的細(xì)節(jié),只保留結(jié)構(gòu)、明暗等基本信息,目的是統(tǒng)一圖片大小,保證后續(xù)圖片都有相同長(zhǎng)度的哈希值,方便距離計(jì)算。網(wǎng)上看到的案例基本都將尺寸縮小為8*8,64個(gè)像素點(diǎn),暫時(shí)不清楚縮小為這個(gè)尺寸的原因,但如果覺(jué)得損失的信息太多,個(gè)人認(rèn)為可以將尺寸適當(dāng)調(diào)大,當(dāng)然像素點(diǎn)多了后續(xù)計(jì)算就會(huì)稍慢一些。
2、灰度化處理。將圖片全部轉(zhuǎn)換為統(tǒng)一的灰度圖。
3、計(jì)算像素均值。計(jì)算像素的灰度平均值(此處均值出現(xiàn))。
4、哈希值計(jì)算。將每個(gè)像素的灰度,與平均值進(jìn)行比較。大于或等于平均值,記為1,小于平均值,記為0,由此生成二進(jìn)制數(shù)組。
5、圖片配對(duì),計(jì)算漢明距離。距離越近,越相似。當(dāng)圖片縮小為8*8時(shí),通常認(rèn)為漢明距離小于10的一組圖片為相似圖片。
前言
有一個(gè)需求:計(jì)算圖片的相似度
需要解決兩個(gè)問(wèn)題:
- 生成 ahash
- 存儲(chǔ)和計(jì)算 ahash 之間的距離
生成 ahash
『生成 ahash』 選用 python 下面的一個(gè) imagehash 庫(kù)。(github:https://github.com/JohannesBuchner/imagehash)
from io import BytesIO
import numpy
import imagehash
from PIL import Image
def create_vector(file: BytesIO) -> bytes:
image = Image.open(file)
hash = imagehash.average_hash(image)
_vector = []
for h in hash.hash:
_vector.extend(h)
vector = bytes(
numpy.packbits(
[
int(v)
for v in _vector
],
axis=-1
).tolist()
)
return vectorcreate_vector 函數(shù)輸出的類型是 bytes,就是二進(jìn)制序列
imagehash.average_hash(image) 輸出的 hash 對(duì)象,hash 對(duì)象有一個(gè) hash 屬性,這個(gè)屬性的類型是 list[list[bool]]打印出來(lái)就是長(zhǎng)下面這樣子,其實(shí)就是一個(gè) 8x8=64 bit 的序列
[[False False False False False False False False]
[ True False False False True False False False]
[False False True True True True False False]
[False False False True True False True True]
[False False True True True False False False]
[False True True True True False False False]
[False True True True True False True True]
[False False False True True False True True]]
向量數(shù)據(jù)庫(kù)
『存儲(chǔ)和計(jì)算 ahash 之間的距離』選用 milvus
創(chuàng)建集合
定義集合:
import settings
from pymilvus import (
connections,
Collection,
FieldSchema,
CollectionSchema,
DataType,
)
from loggers import logger
connections.connect(
host=settings.MILVUS_CONFIG.host,
port=settings.MILVUS_CONFIG.port,
)
schema = CollectionSchema([
FieldSchema("id", DataType.INT64, is_primary=True, auto_id=True),
FieldSchema("meta_id", DataType.INT64),
FieldSchema("company_id", DataType.INT64),
FieldSchema("image_vector", dtype=DataType.BINARY_VECTOR, dim=64)
])
# 集合不存在,則會(huì)自動(dòng)創(chuàng)建集合;已存在,不會(huì)重復(fù)創(chuàng)建
collection = Collection(settings.MILVUS_CONFIG.collection.name, schema)使用的向量類型是 dtype=DataType.BINARY_VECTOR,
為什么不選 float 是因?yàn)槲也恢涝趺窗?ahash 轉(zhuǎn)成 float
插入 ahash 到 milvus
class TestVector(unittest.TestCase):
def test_insert_vector(self):
"""
插入 ahash 到 milvus
python -m unittest testing.test_milvus.TestVector.test_insert_vector
"""
oss_file_path = 'image_hash/testing/WechatIMG193.jpeg'
file = BytesIO(bucket.get_object(oss_file_path).read())
vector = create_vector(file)
m_pk = insert_vector(vector, meta_id=2, company_id=1)
logger.debug(f'milvus pk: {m_pk}')查詢 ahash from milvus
def test_search(self):
"""
批量調(diào)用后端接口入庫(kù)
python -m unittest testing.test_milvus.TestVector.test_search
"""
oss_file_path = 'image_hash/testing/WechatIMG193.jpeg'
file = BytesIO(open(BASE_DIR/'testing'/'resource'/'WechatIMG193.jpeg','rb').read())
vector = create_vector(file)
logger.debug(vector)
rows: list[dict[str, Any]] = collection.search(
data=[vector],
param={"metric_type": 'L2', "params": {"nprobe": 32}},
anns_field='image_vector',
output_fields=['id', 'meta_id', 'company_id'],
limit=10,
)
logger.debug(rows)
logger.debug(type(rows))到此這篇關(guān)于Python使用imagehash庫(kù)生成ahash算法的示例代碼的文章就介紹到這了,更多相關(guān)Python imagehash生成ahash內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
numpy數(shù)據(jù)類型dtype轉(zhuǎn)換實(shí)現(xiàn)
這篇文章主要介紹了numpy數(shù)據(jù)類型dtype轉(zhuǎn)換實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04
python timestamp和datetime之間轉(zhuǎn)換詳解
這篇文章主要為大家詳細(xì)介紹了python timestamp和datetime之間轉(zhuǎn)換,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-12-12
Request的中斷和ErrorHandler實(shí)例解析
這篇文章主要介紹了Request的中斷和ErrorHandler實(shí)例解析,分享了相關(guān)代碼示例,小編覺(jué)得還是挺不錯(cuò)的,具有一定借鑒價(jià)值,需要的朋友可以參考下2018-02-02
Python實(shí)現(xiàn)Excel自動(dòng)分組合并單元格
這篇文章主要為大家詳細(xì)介紹了Python實(shí)現(xiàn)Excel自動(dòng)分組合并單元格,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-02-02
Pytorch mask-rcnn 實(shí)現(xiàn)細(xì)節(jié)分享
這篇文章主要介紹了Pytorch mask-rcnn 實(shí)現(xiàn)細(xì)節(jié)分享,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-06-06
python3 實(shí)現(xiàn)的人人影視網(wǎng)站自動(dòng)簽到
這里給大家分享的是使用Python3結(jié)合計(jì)劃任務(wù),實(shí)現(xiàn)的人人影視網(wǎng)站自動(dòng)簽到功能的代碼,非常的實(shí)用,有需要的小伙伴可以參考下2016-06-06
Python替換Excel表格中的空值或指定值的實(shí)現(xiàn)
本文介紹了使用Python的pandas庫(kù)結(jié)合openpyxl來(lái)批量替換Excel表格中的空值或指定值,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-12-12
python重試裝飾器的簡(jiǎn)單實(shí)現(xiàn)方法
今天小編就為大家分享一篇python重試裝飾器的簡(jiǎn)單實(shí)現(xiàn)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-01-01

