ใฏใใใซ
ใคใณใฟใผใใใไธใใๅ้ใใ็ปๅใใใจใซๆฉๆขฐๅญฆ็ฟใฎใใผใฟใปใใใไฝๆใใใจใใ้่คใใ็ปๅใฎๅ้คใๅฟ ่ฆใงใใ่จ็ทดใใผใฟใซ้่คใใ็ปๅใใใใชใใพใ ่ฏใใงใใใ่จ็ทดใใผใฟใปใในใใใผใฟใฎ้ใง้่คใใ็ปๅใใใใจใใใใใleakageใ่ตทใใฆใใพใใพใใ
็ปๅใฎ้่คใๆคๅบใใๆนๆณใจใใฆๆใๅ็ดใชใใฎใฏใMD5ใชใฉใฎใใกใคใซใฎใใใทใฅๅคใๅฉ็จใใใใจใงใใใใใใชใใใใใกใคใซใฎใใใทใฅๅคใฏใใใใพใงใ็ปๅใใกใคใซใฎใใคใใชๅใใใใทใฅๅใใใใฎใงใใใๅใ็ปๅใงใไฟๅญๅฝขๅผใๅง็ธฎใใฉใกใผใฟใๅคใใใ ใใงใๅคๅใใฆใใพใใๆคๅบๆผใใซใคใชใใใพใใ
ใใใงๆฌ่จไบใงใฏใ็ปๅใฎ็นๅพดใใฎใใฎใใใใทใฅๅใใใขใซใดใชใบใ ใ็ดนไปใใใจใจใใซใ็ฐกๅใชๅฎ้จใ้ใใฆใใใใใใทใฅๅใขใซใดใชใบใ ใฎ็นๆงใ่ฆใฆใใใพใใ
็ปๅใฎใใใทใฅๅใขใซใดใชใบใ
Average Hash (aHash)
็ปๅใฎ็นๅพด๏ผ่ผๅบฆใใฟใผใณ๏ผใใใจใซใใใใใทใฅๅคใงใ็ด ๆดใชใขใซใดใชใบใ ใง่จ็ฎใงใใพใใๅ ทไฝ็ใชๆ้ ใฏไปฅไธใฎ้ใใงใใ
- ็ปๅใ8x8 pixels ใซ็ธฎๅฐใใใ
- ใใใซใฐใฌใผในใฑใผใซใซๅคๆใใใ
- ็ป็ด ๅคใฎๅนณๅใๆฑใใใ
- 8x8 pixels ใฎๅ็ป็ด ใซๅฏพใใๅนณๅๅคใใใ้ซใใไฝใใใง2ๅคๅ (0 or 1) ใใใ
- 2ๅคใฎใทใผใฑใณในใซใคใใฆใใฉในใฟในใญใฃใณ้ ใชใฉไฝใใใฎ้ ใงไธๅใซใใ64bitใฎใใใทใฅใๅพใใ
aHashใซใฏใใขใซใดใชใบใ ใ็ฐกๅใงใใค่จ็ฎใ้ใใจใใ้ทๆใใใใพใใไธๆนใงใๆ่ปๆงใซๆฌ ใใๆฌ ็นใใใใพใใไพใใฐใใฌใณใ่ฃๆญฃใใ็ปๅใฎใใใทใฅๅคใฏใๅ ใฎ็ปๅใจ่ท้ขใ้ ใใชใฃใฆใใพใใพใใ
Perseptual Hash (pHash)
aHashใฏ็ป็ด ๅคใใฎใใฎใไฝฟใใพใใใใpHashใงใฏ็ปๅใฎ้ขๆฃใณใตใคใณๅคๆ (DCT) ใไฝฟใใพใใDCTใฏใ็ปๅใชใฉใฎไฟกๅทใๅจๆณขๆฐ้ ๅใซๅคๆใใๆนๆณใฎใฒใจใคใงใไพใใฐJPEGใฎๅง็ธฎใซๅฉ็จใใใฆใใพใใJPEGๅง็ธฎใงใฏใ็ปๅใDCTใใไบบ้ใ็ฅ่ฆใใใใไฝๅจๆณขๆฐๆๅใฎใฟใๅใๅบใใใจใงใใใผใฟ้ใๅๆธใใฆใใพใใ
JPGEๅง็ธฎใจๅๆงใซใpHashใงใ็ปๅใฎDCTใซใใใไฝๅจๆณขๆฐๆๅใซ็็ฎใใใใใใใใใทใฅๅใใพใใใใใใใใจใงใไบบ้ใ็ฅ่ฆใใใใ็นๅพดใๅชๅ ใใฆๆฝๅบใใใใจใใงใใใพใ็ปๅใฎๅนณ่ก็งปๅใ่ผๅบฆๅคๅใซๅฏพใใฆใญใในใใชใใใทใฅๅใใงใใใจ่ใใใใพใใ
- ็ปๅใ็ธฎๅฐใใใ8x8ใใใๅคงใใใตใคใบใซใใ๏ผไพใใฐ32x32ใชใฉ๏ผใ
- ใฐใฌใผในใฑใผใซๅใใใ
- DCTใใใ
- ไฝๅจๆณขๆฐๆๅใฎ8x8ใ ใใๅใๅบใใ
- ็ดๆตๆๅใ้คใใไฝๅจๆณขๆฐๆๅใฎๅนณๅๅคใ็ฎๅบใใใ
- ๅนณๅๅคใใใ้ซใใไฝใใใง2ๅคๅใใใ
- ใฉในใฟในใญใฃใณ้ ใชใฉไฝใใใฎ้ ใงไธๅใซใใ64bitใฎใใใทใฅใๅพใใ
ใใฎไปใฎxHash
aHash, pHashใฎไปใซใใใใพใใพใชใใชใจใผใทใงใณใใใใใใงใใใใณใใใผใฏใใใฆใใใฆใใไบบใใใพใ1ใ
ๅฎ้จ
็ปๅใซๅฏพใใฆใใพใใพใชๅฆ็ใๅ ใใๅ ็ปๅใจใฎใใใทใฅๅคใๆฏ่ผใใฆใฟใพใใใใใทใฅๅคใจใใฆใaHash, pHashใใใใใ่จ็ฎใใพใใ
ใพใใResNet50ใฎๆ็ตๅฑคใฎ็ดๅใฎๅฑคใซใคใใฆใๅบๅใใใใทใฅใจใฟใชใใใจใใๆๆณใ่ฉฆใใฆใฟใพใใใใฎๆๆณใฏใใ่ซๆ2ใงๆก็จใใใฆใใๆนๆณใงใ3ใ
ใณใผใ
aHashใใใณpHashใฎ่จ็ฎใซใฏOpenCVใไฝฟใฃใฆใใพใใใImageHashใจใใใฉใคใใฉใชใใใใใใงใใใพใใaHashใใใณpHashใงใฏใใใใทใฅๅคใฎๆฏ่ผใซใใใณใฐ่ท้ขใไฝฟใใพใใๅคๅใฏ [0, 64] ใงใใใใฎๅคๅใซๅใใใใใใResNet50ใๅฉ็จใใใใใทใฅ๏ผใใฉใ๏ผใฎๆฏ่ผใงใฏใใณใตใคใณ้กไผผๅบฆใ่จ็ฎใใๅพใซๅ่ฟฐใฎๅคๅใธๅคๆใใฆใใพใใ
import copy
import pprint
import cv2.cv2 as cv2
import numpy as np
from keras import models
from keras.applications.resnet50 import ResNet50, preprocess_input
from sklearn.metrics.pairwise import cosine_similarity
class ImagePairGenerator(object):
"""
ๅฎ้จ็จใฎ็ปๅใใขใ็ๆใใใฏใฉใน
"""
def __init__(self, img: np.ndarray):
self._img = img
self._processings = self._prepare_processings()
def _prepare_processings(self):
h, w, _ = self._img.shape
# lenna็ปๅใฎ้กใฎใใใใๅใๆใใใใฎไฝ็ฝฎใจใตใคใบ
org = np.array([128, 128])
size = np.array([256, 256])
# kind (processing description), img1, img2
processings = [
('ๅไธ',
lambda x: x,
lambda x: x),
('ใฐใฌใผในใฑใผใซๅ',
lambda x: x,
lambda x: cv2.cvtColor(
cv2.cvtColor(x, cv2.COLOR_BGR2GRAY), cv2.COLOR_GRAY2BGR)),
*list(map(lambda s:
(f'1/{s:2}ใซ็ธฎๅฐ',
lambda x: x,
lambda x: cv2.resize(x, (w // s, h // s))),
np.power(2, range(1, 5)))),
*list(map(lambda s:
(f'ๅนณๆปๅ (kernel size = {s:2}',
lambda x: x,
lambda x: cv2.blur(x, (s, s))),
[3, 5, 7, 9, 11])),
*list(map(lambda s:
(f'ใใญในใๆฟๅ
ฅ (fontScale = {s})',
lambda x: x,
lambda x: cv2.putText(x, 'Text', org=(10, 30*s),
fontFace=cv2.FONT_HERSHEY_SIMPLEX,
fontScale=s,
color=(255, 255, 255),
thickness=3*s,
lineType=cv2.LINE_AA)),
range(1, 8))),
*list(map(lambda q:
(f'JPEGๅง็ธฎ (quality = {q})',
lambda x: x,
lambda x: img_encode_decode(x, q)),
range(10, 100, 10))),
*list(map(lambda gamma:
(f'ใฌใณใ่ฃๆญฃ (gamma = {gamma})',
lambda x: x,
lambda x: img_gamma(x, gamma)),
[0.2, 0.5, 0.8, 1.2, 1.5, 2.0])),
*list(map(lambda d:
(f'ๅนณ่ก็งปๅ ({d:2} pixels)',
lambda x: img_crop(x, org, size),
lambda x: img_crop(x, org + d, size)),
np.power(2, range(7)))),
]
return processings
def __iter__(self):
for kind, p1, p2 in self._processings:
yield (kind,
p1(copy.deepcopy(self._img)),
p2(copy.deepcopy(self._img)))
class ResNet50Hasher(object):
"""
ResNet50ใฎๆ็ตๅฑคใใใใทใฅๅคใจใใฆๅบๅใใใใใฎใฏใฉใน
"""
_input_size = 224
def __init__(self):
self._model = self._prepare_model()
def _prepare_model(self):
resnet50 = ResNet50(include_top=False, weights='imagenet',
input_shape=(self._input_size, self._input_size, 3),
pooling='avg')
model = models.Sequential()
model.add(resnet50)
return model
def compute(self, img: np.ndarray) -> np.ndarray:
img_arr = np.array([
cv2.resize(img, (self._input_size, self._input_size))
])
img_arr = preprocess_input(img_arr)
embeddings = self._model.predict(img_arr)
return embeddings
@staticmethod
def compare(x1: np.ndarray, x2: np.ndarray):
"""
ใณใตใคใณ้กไผผๅบฆใ่จ็ฎใใใๅคๅใฏ [0, 1]ใ
aHashใใใณpHashใๆฏ่ผใใใใใณใฐ่ท้ขใซๅใใใฆใ
[0, 64] ใฎๅคๅใซๅคๆใใใ
"""
cs = cosine_similarity(x1, x2)
distance = 64 + (0 - 64) * ((cs - 0) / (1 - 0))
return distance.ravel()[0] # np.array -> float
def img_crop(img: np.ndarray, org: np.ndarray, size: np.ndarray) -> np.ndarray:
"""
็ปๅใใไปปๆใฎ้ ๅใๅใๆใใ
"""
y, x = org
h, w = size
return img[y:y + h, x:x + w, :]
def img_encode_decode(img: np.ndarray, quality=90) -> np.ndarray:
"""
Jpegๅง็ธฎใฎๅฃๅใๅ็พใใใ
ๅ่๏ผhttps://qiita.com/ka10ryu1/items/5fed6b4c8f29163d0d65
"""
encode_param = [int(cv2.IMWRITE_JPEG_QUALITY), quality]
_, enc_img = cv2.imencode('.jpg', img, encode_param)
dec_img = cv2.imdecode(enc_img, cv2.IMREAD_COLOR)
return dec_img
def img_gamma(img: np.ndarray, gamma=0.5) -> np.ndarray:
"""
ใฌใณใ่ฃๆญฃใใใ
ๅ่๏ผhttps://www.dogrow.net/python/blog99/
"""
lut = np.empty((1, 256), np.uint8)
for i in range(256):
lut[0, i] = np.clip(pow(i / 255.0, gamma) * 255.0, 0, 255)
return cv2.LUT(img, lut)
def image_hashing_test():
image_path = 'resources/lena_std.tif'
img = cv2.imread(image_path, cv2.IMREAD_COLOR)
h, w, _ = img.shape
hashers = [
('aHash', cv2.img_hash.AverageHash_create()),
('pHash', cv2.img_hash.PHash_create()),
('ResNet', ResNet50Hasher())
]
pairs = ImagePairGenerator(img)
result_dict = {}
for pair_kind, img1, img2 in pairs:
result_dict[pair_kind] = {}
for hasher_kind, hasher in hashers:
hash1 = hasher.compute(img1)
hash2 = hasher.compute(img2)
distance = hasher.compare(hash1, hash2)
result_dict[pair_kind][hasher_kind] = distance
# ็ปๅใ็ฎ่ฆใง็ขบ่ช๏ผshapeใๅใใจใใ ใใๆใใใฎใ้ขๅใชใฎใง๏ผ
if img1.shape == img2.shape:
window_name = pair_kind
cv2.imshow(window_name, cv2.hconcat((img1, img2)))
cv2.waitKey()
cv2.destroyWindow(window_name)
pprint.pprint(result_dict)
if __name__ == '__main__':
image_hashing_test()
็ตๆ
{'ๅไธ': {'ResNet': 0.0, 'aHash': 0.0, 'pHash': 0.0},
'ใฐใฌใผในใฑใผใซๅ': {'ResNet': 14.379967, 'aHash': 0.0, 'pHash': 0.0},
'1/ 2ใซ็ธฎๅฐ': {'ResNet': 1.2773285, 'aHash': 3.0, 'pHash': 1.0},
'1/ 4ใซ็ธฎๅฐ': {'ResNet': 6.5748253, 'aHash': 4.0, 'pHash': 1.0},
'1/ 8ใซ็ธฎๅฐ': {'ResNet': 18.959282, 'aHash': 7.0, 'pHash': 3.0},
'1/16ใซ็ธฎๅฐ': {'ResNet': 34.8299, 'aHash': 12.0, 'pHash': 0.0},
'JPEGๅง็ธฎ (quality = 10)': {'ResNet': 6.4169083, 'aHash': 2.0, 'pHash': 0.0},
'JPEGๅง็ธฎ (quality = 20)': {'ResNet': 2.6065674, 'aHash': 1.0, 'pHash': 0.0},
'JPEGๅง็ธฎ (quality = 30)': {'ResNet': 1.8446579, 'aHash': 0.0, 'pHash': 0.0},
'JPEGๅง็ธฎ (quality = 40)': {'ResNet': 1.2492218, 'aHash': 0.0, 'pHash': 1.0},
'JPEGๅง็ธฎ (quality = 50)': {'ResNet': 1.0534592, 'aHash': 0.0, 'pHash': 0.0},
'JPEGๅง็ธฎ (quality = 60)': {'ResNet': 0.99293137, 'aHash': 0.0, 'pHash': 0.0},
'JPEGๅง็ธฎ (quality = 70)': {'ResNet': 0.7313309, 'aHash': 0.0, 'pHash': 0.0},
'JPEGๅง็ธฎ (quality = 80)': {'ResNet': 0.58068085, 'aHash': 0.0, 'pHash': 0.0},
'JPEGๅง็ธฎ (quality = 90)': {'ResNet': 0.354187, 'aHash': 0.0, 'pHash': 0.0},
'ใฌใณใ่ฃๆญฃ (gamma = 0.2)': {'ResNet': 16.319721, 'aHash': 2.0, 'pHash': 1.0},
'ใฌใณใ่ฃๆญฃ (gamma = 0.5)': {'ResNet': 4.2003975, 'aHash': 2.0, 'pHash': 0.0},
'ใฌใณใ่ฃๆญฃ (gamma = 0.8)': {'ResNet': 0.48334503, 'aHash': 0.0, 'pHash': 0.0},
'ใฌใณใ่ฃๆญฃ (gamma = 1.2)': {'ResNet': 0.381176, 'aHash': 0.0, 'pHash': 1.0},
'ใฌใณใ่ฃๆญฃ (gamma = 1.5)': {'ResNet': 1.7187691, 'aHash': 2.0, 'pHash': 1.0},
'ใฌใณใ่ฃๆญฃ (gamma = 2.0)': {'ResNet': 4.074257, 'aHash': 6.0, 'pHash': 2.0},
'ใใญในใๆฟๅ
ฅ (fontScale = 1)': {'ResNet': 0.7838249, 'aHash': 0.0, 'pHash': 0.0},
'ใใญในใๆฟๅ
ฅ (fontScale = 2)': {'ResNet': 1.0911484, 'aHash': 0.0, 'pHash': 1.0},
'ใใญในใๆฟๅ
ฅ (fontScale = 3)': {'ResNet': 2.7721176, 'aHash': 0.0, 'pHash': 2.0},
'ใใญในใๆฟๅ
ฅ (fontScale = 4)': {'ResNet': 4.646305, 'aHash': 0.0, 'pHash': 4.0},
'ใใญในใๆฟๅ
ฅ (fontScale = 5)': {'ResNet': 8.435852, 'aHash': 2.0, 'pHash': 3.0},
'ใใญในใๆฟๅ
ฅ (fontScale = 6)': {'ResNet': 11.267036, 'aHash': 6.0, 'pHash': 3.0},
'ใใญในใๆฟๅ
ฅ (fontScale = 7)': {'ResNet': 15.272251, 'aHash': 2.0, 'pHash': 7.0},
'ๅนณๆปๅ (kernel size = 3': {'ResNet': 1.3798943, 'aHash': 2.0, 'pHash': 0.0},
'ๅนณๆปๅ (kernel size = 5': {'ResNet': 3.1528091, 'aHash': 4.0, 'pHash': 1.0},
'ๅนณๆปๅ (kernel size = 7': {'ResNet': 4.903698, 'aHash': 4.0, 'pHash': 1.0},
'ๅนณๆปๅ (kernel size = 9': {'ResNet': 6.8400574, 'aHash': 4.0, 'pHash': 1.0},
'ๅนณๆปๅ (kernel size = 11': {'ResNet': 9.477722, 'aHash': 5.0, 'pHash': 2.0},
'ๅนณ่ก็งปๅ ( 1 pixels)': {'ResNet': 0.47764206, 'aHash': 6.0, 'pHash': 0.0},
'ๅนณ่ก็งปๅ ( 2 pixels)': {'ResNet': 0.98942566, 'aHash': 10.0, 'pHash': 3.0},
'ๅนณ่ก็งปๅ ( 4 pixels)': {'ResNet': 1.475399, 'aHash': 15.0, 'pHash': 5.0},
'ๅนณ่ก็งปๅ ( 8 pixels)': {'ResNet': 2.587471, 'aHash': 20.0, 'pHash': 13.0},
'ๅนณ่ก็งปๅ (16 pixels)': {'ResNet': 3.1883087, 'aHash': 25.0, 'pHash': 21.0},
'ๅนณ่ก็งปๅ (32 pixels)': {'ResNet': 4.8445663, 'aHash': 23.0, 'pHash': 31.0},
'ๅนณ่ก็งปๅ (64 pixels)': {'ResNet': 9.34531, 'aHash': 28.0, 'pHash': 30.0}}
โปๅฎ้ใซๅพใใใๅบๅใซๅฏพใใๅฏ่ฆๆงๅไธใฎใใ้ ๅบใฎๅ ฅใๆฟใใจใคใณใใณใใฎ่ชฟๆดใใใฆใใพใใ
่ๅฏ
ResNetใฏใใใพใงใImageNetใงไบๅๅญฆ็ฟใใใใใฎใใใฎใพใพไฝฟใฃใฆใใใใจใซๆณจๆใใฆใใ ใใใใใชใใกใๅญฆ็ฟใใผใฟใ็จๆใใใใจใซใใฃใฆใไปฅไธใง่ฟฐในใใใฆใใใใฎใจใฏ็ฐใชใ็นๆงใๆใฃใใใใใฏใผใฏใ็ฒๅพใใใใจใใงใใใจ่ใใใใพใใ
ใพใใ็ปๅใซใใฃใฆใๅพๅใๅคใใๅฏ่ฝๆงใใใใพใใๅฎ็จใใใชใใใใ็จๅบฆใกใใใจใใใใผใฟใปใใใง่ฉไพกใใใฎใใใใงใใใใ
- ๅไธ๏ผๅฝใใๅใงใใใใฉใฎใใใทใฅๆนๆณใงใ่ท้ขใ0ใซใชใฃใฆใใพใใ
- ใฐใฌใผในใฑใผใซๅ๏ผaHashใpHashใงใฏๅฆ็ใฎๆๅใงใฐใฌใผในใฑใผใซๅใใใใใๅ ็ปๅใจใฎ่ท้ขใ0ใซใชใฃใฆใใพใใ
- ็ธฎๅฐ๏ผResNetใaHashใงใฏใในใฑใผใซใซๅฏพๅฟใใฆ่ท้ขใ้ขใใฆใใใพใใใpHashใฏๆฏ่ผ็ใญใในใใงใใ
- JPEGๅง็ธฎ๏ผResNetใงใฏๅง็ธฎ็ใซๆฏไพใใฆใใใใใซ่ฆใใใฎใ่ๅณๆทฑใใงใใๅฏพใใฆaHashใpHashใฏๆฏ่ผ็ใญใในใใงใใๅ็ดใชใใใทใฅๅใฎใขใซใดใชใบใ ๏ผๅนณๅๅคใซๅฏพใใ้ซไฝใงใฎใจใณใณใผใ๏ผใใๅง็ธฎใซใใๅฃๅใซๅฏพใใฆใใญใในใใชใฎใใใใใพใใใ
- ใฌใณใ่ฃๆญฃ๏ผResNetใจๆฏ่ผใใใจใaHashใpHashใฎๆนใๆฏ่ผ็ใญใในใใชใใใงใใ
- ใใญในใๆฟๅ ฅ๏ผaHashใๆฏ่ผ็ใญใในใใชใใใงใใๆฟๅ ฅใใใใใญในใใฎ่ฒใซๅใใใฆใ็ปๅๅ ใฎ็ป็ด ๅคใฎๅนณๅใๅคๅใใใจใณใณใผใ็ตๆใๅคใใฃใฆใใชใใใจใ่ใใใใพใใๅฏพใใฆpHashใResNetใงใฏใใญในใใฎๅคงใใใซไผดใฃใฆ่ท้ขใ้ใใฆใใพใใ
- ๅนณๆปๅ๏ผpHashใๆฏ่ผ็ใญใในใใงใใใใใฏใไฝๅจๆณขๆฐๆๅใฎใฟใซ็็ฎใใฆใใใใใงใใใใ
- ๅนณ่ก็งปๅ๏ผใฉใฎใใใทใฅใใๅนณ่ก็งปๅ้ใซไผดใฃใฆ่ท้ขใ้ขใใฆใใใพใใResNetใๆฏ่ผ็ใญใในใใงใใใใใ
ใพใจใ
็ปๅใใใใทใฅๅใใๆๆณใ็ดนไปใใพใใใๅ ใใฆใใใใคใใฎๅฆ็ใๅ ใใ็ปๅใจๅ ็ปๅใจใฎ่ท้ขใๆธฌๅฎใใๅใใใทใฅๅๆๆณใฎ็นๆงใ่ฆณๅฏใใพใใใๆฌ่จไบใงๆฏ่ผใใใขใซใดใชใบใ ใฎไธญใงใฏใpHashใใ็ปๅใฎในใฑใผใชใณใฐใๅง็ธฎใซใใๅฃๅใๅนณๆปๅใซๅฏพใใฆใญใในใใงใใๅพๅใ่ฆณๅฏใงใใพใใใ
็งใฏxHash็ณปใฎใขใซใดใชใบใ ใๆ่ฟ็ฅใฃใใฎใงใใใใทใณใใซใงใใคใใใขใคใใขใซๅบใฅใใขใซใดใชใบใ ใงใใใจๆใใพใใๆฏ่ผ็ๆฏใใใขใซใดใชใบใ ใงใฏใใใจๆใใพใใใ้ฉๆ้ฉๆใงไฝฟใใใชใใใใใซใชใใจใใใงใใญใ
ๅ่
-
Looks Like It - The Hacker Factor Blog
http://www.hackerfactor.com/blog/index.php?/archives/432-Looks-Like-It.html -
perceptual hash(phash)ใๅฉ็จใใฆ็ปๅๆฏ่ผใใใฆใฟใ
http://hideack.hatenablog.com/entry/2015/03/16/194336 -
OpenCV: The module brings implementations of different image hashing algorithms.
https://docs.opencv.org/4.5.0/d4/d93/group__img__hash.html
OpenCVใซๅฎ่ฃ ใใใฆใใใใใทใฅๅใขใซใดใชใบใ ใซใคใใฆใฏใใใใฉใผใใณในใใฃใผใใๅ ฌ้ใใใฆใใพใใ
-
C. Zauner, "Implementation and Benchmarking of Perceptual Image Hash Functions," Upper Austria University of Applied Sciences, Hagenberg Campus, 2010. โฉ
-
Recipe1M+: A Dataset for Learning Cross-Modal Embeddings for Cooking Recipes and Food Images - MIT โฉ
-
ๅฎใ่จใใจใใใฎ่ซๆใ่ชญใใงใใใจใใซใใใฃใจ็ฐกๅใซ้่คใ่ฆๅใใๆนๆณใใใใฎใงใฏ๏ผใใจๆใ็ซใฃใใฎใใๆฌ่จไบใๆธใใใฃใใใงใใ โฉ
Comments
Let's comment your feelings that are more than good