Why not login to Qiita and try out its useful features?

We'll deliver articles that match you.

You can read useful information later.

81
66

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ๅŒไธ€็”ปๅƒใ‚’ๅˆคๅฎšใ™ใ‚‹ใŸใ‚ใฎใƒใƒƒใ‚ทใƒฅๅŒ–ใ‚ขใƒซใ‚ดใƒชใ‚บใƒ 

Last updated at Posted at 2019-11-18

ใฏใ˜ใ‚ใซ

ใ‚คใƒณใ‚ฟใƒผใƒใƒƒใƒˆไธŠใ‹ใ‚‰ๅŽ้›†ใ—ใŸ็”ปๅƒใ‚’ใ‚‚ใจใซๆฉŸๆขฐๅญฆ็ฟ’ใฎใƒ‡ใƒผใ‚ฟใ‚ปใƒƒใƒˆใ‚’ไฝœๆˆใ™ใ‚‹ใจใใ€้‡่ค‡ใ—ใŸ็”ปๅƒใฎๅ‰Š้™คใŒๅฟ…่ฆใงใ™ใ€‚่จ“็ทดใƒ‡ใƒผใ‚ฟใซ้‡่ค‡ใ—ใŸ็”ปๅƒใŒใ‚ใ‚‹ใชใ‚‰ใพใ ่‰ฏใ„ใงใ™ใŒใ€่จ“็ทดใƒ‡ใƒผใ‚ฟใƒปใƒ†ใ‚นใƒˆใƒ‡ใƒผใ‚ฟใฎ้–“ใง้‡่ค‡ใ—ใŸ็”ปๅƒใŒใ‚ใ‚‹ใจใ€ใ„ใ‚ใ‚†ใ‚‹leakageใŒ่ตทใใฆใ—ใพใ„ใพใ™ใ€‚

็”ปๅƒใฎ้‡่ค‡ใ‚’ๆคœๅ‡บใ™ใ‚‹ๆ–นๆณ•ใจใ—ใฆๆœ€ใ‚‚ๅ˜็ด”ใชใ‚‚ใฎใฏใ€MD5ใชใฉใฎใƒ•ใ‚กใ‚คใƒซใฎใƒใƒƒใ‚ทใƒฅๅ€คใ‚’ๅˆฉ็”จใ™ใ‚‹ใ“ใจใงใ™ใ€‚ใ—ใ‹ใ—ใชใŒใ‚‰ใ€ใƒ•ใ‚กใ‚คใƒซใฎใƒใƒƒใ‚ทใƒฅๅ€คใฏใ€ใ‚ใใพใงใ‚‚็”ปๅƒใƒ•ใ‚กใ‚คใƒซใฎใƒใ‚คใƒŠใƒชๅˆ—ใ‚’ใƒใƒƒใ‚ทใƒฅๅŒ–ใ—ใŸใ‚‚ใฎใงใ‚ใ‚Šใ€ๅŒใ˜็”ปๅƒใงใ‚‚ไฟๅญ˜ๅฝขๅผใ‚„ๅœง็ธฎใƒ‘ใƒฉใƒกใƒผใ‚ฟใ‚’ๅค‰ใˆใŸใ ใ‘ใงใ‚‚ๅค‰ๅŒ–ใ—ใฆใ—ใพใ„ใ€ๆคœๅ‡บๆผใ‚ŒใซใคใชใŒใ‚Šใพใ™ใ€‚

ใใ“ใงๆœฌ่จ˜ไบ‹ใงใฏใ€็”ปๅƒใฎ็‰นๅพดใใฎใ‚‚ใฎใ‚’ใƒใƒƒใ‚ทใƒฅๅŒ–ใ™ใ‚‹ใ‚ขใƒซใ‚ดใƒชใ‚บใƒ ใ‚’็ดนไป‹ใ™ใ‚‹ใจใจใ‚‚ใซใ€็ฐกๅ˜ใชๅฎŸ้จ“ใ‚’้€šใ—ใฆใใ‚Œใ‚‰ใƒใƒƒใ‚ทใƒฅๅŒ–ใ‚ขใƒซใ‚ดใƒชใ‚บใƒ ใฎ็‰นๆ€งใ‚’่ฆ‹ใฆใ„ใใพใ™ใ€‚

็”ปๅƒใฎใƒใƒƒใ‚ทใƒฅๅŒ–ใ‚ขใƒซใ‚ดใƒชใ‚บใƒ 

Average Hash (aHash)

็”ปๅƒใฎ็‰นๅพด๏ผˆ่ผๅบฆใƒ‘ใ‚ฟใƒผใƒณ๏ผ‰ใ‚’ใ‚‚ใจใซใ—ใŸใƒใƒƒใ‚ทใƒฅๅ€คใงใ€็ด ๆœดใชใ‚ขใƒซใ‚ดใƒชใ‚บใƒ ใง่จˆ็ฎ—ใงใใพใ™ใ€‚ๅ…ทไฝ“็š„ใชๆ‰‹้ †ใฏไปฅไธ‹ใฎ้€šใ‚Šใงใ™ใ€‚

  1. ็”ปๅƒใ‚’8x8 pixels ใซ็ธฎๅฐใ™ใ‚‹ใ€‚
  2. ใ•ใ‚‰ใซใ‚ฐใƒฌใƒผใ‚นใ‚ฑใƒผใƒซใซๅค‰ๆ›ใ™ใ‚‹ใ€‚
  3. ็”ป็ด ๅ€คใฎๅนณๅ‡ใ‚’ๆฑ‚ใ‚ใ‚‹ใ€‚
  4. 8x8 pixels ใฎๅ„็”ป็ด ใซๅฏพใ—ใ€ๅนณๅ‡ๅ€คใ‚ˆใ‚Šใ‚‚้ซ˜ใ„ใ‹ไฝŽใ„ใ‹ใง2ๅ€คๅŒ– (0 or 1) ใ™ใ‚‹ใ€‚
  5. 2ๅ€คใฎใ‚ทใƒผใ‚ฑใƒณใ‚นใซใคใ„ใฆใ€ใƒฉใ‚นใ‚ฟใ‚นใ‚ญใƒฃใƒณ้ †ใชใฉไฝ•ใ‚‰ใ‹ใฎ้ †ใงไธ€ๅˆ—ใซใ—ใ€64bitใฎใƒใƒƒใ‚ทใƒฅใ‚’ๅพ—ใ‚‹ใ€‚

aHashใซใฏใ€ใ‚ขใƒซใ‚ดใƒชใ‚บใƒ ใŒ็ฐกๅ˜ใงใ‹ใค่จˆ็ฎ—ใŒ้€Ÿใ„ใจใ„ใ†้•ทๆ‰€ใŒใ‚ใ‚Šใพใ™ใ€‚ไธ€ๆ–นใงใ€ๆŸ”่ปŸๆ€งใซๆฌ ใ‘ใ‚‹ๆฌ ็‚นใ‚‚ใ‚ใ‚Šใพใ™ใ€‚ไพ‹ใˆใฐใ€ใ‚ฌใƒณใƒž่ฃœๆญฃใ—ใŸ็”ปๅƒใฎใƒใƒƒใ‚ทใƒฅๅ€คใฏใ€ๅ…ƒใฎ็”ปๅƒใจ่ท้›ขใŒ้ ใใชใฃใฆใ—ใพใ„ใพใ™ใ€‚

Perseptual Hash (pHash)

aHashใฏ็”ป็ด ๅ€คใใฎใ‚‚ใฎใ‚’ไฝฟใ„ใพใ—ใŸใŒใ€pHashใงใฏ็”ปๅƒใฎ้›ขๆ•ฃใ‚ณใ‚ตใ‚คใƒณๅค‰ๆ› (DCT) ใ‚’ไฝฟใ„ใพใ™ใ€‚DCTใฏใ€็”ปๅƒใชใฉใฎไฟกๅทใ‚’ๅ‘จๆณขๆ•ฐ้ ˜ๅŸŸใซๅค‰ๆ›ใ™ใ‚‹ๆ–นๆณ•ใฎใฒใจใคใงใ€ไพ‹ใˆใฐJPEGใฎๅœง็ธฎใซๅˆฉ็”จใ•ใ‚Œใฆใ„ใพใ™ใ€‚JPEGๅœง็ธฎใงใฏใ€็”ปๅƒใ‚’DCTใ—ใ€ไบบ้–“ใŒ็Ÿฅ่ฆšใ—ใ‚„ใ™ใ„ไฝŽๅ‘จๆณขๆ•ฐๆˆๅˆ†ใฎใฟใ‚’ๅ–ใ‚Šๅ‡บใ™ใ“ใจใงใ€ใƒ‡ใƒผใ‚ฟ้‡ใ‚’ๅ‰Šๆธ›ใ—ใฆใ„ใพใ™ใ€‚

JPGEๅœง็ธฎใจๅŒๆง˜ใซใ€pHashใงใ‚‚็”ปๅƒใฎDCTใซใŠใ‘ใ‚‹ไฝŽๅ‘จๆณขๆ•ฐๆˆๅˆ†ใซ็€็›ฎใ—ใ€ใใ‚Œใ‚‰ใ‚’ใƒใƒƒใ‚ทใƒฅๅŒ–ใ—ใพใ™ใ€‚ใ“ใ†ใ™ใ‚‹ใ“ใจใงใ€ไบบ้–“ใŒ็Ÿฅ่ฆšใ—ใ‚„ใ™ใ„็‰นๅพดใ‚’ๅ„ชๅ…ˆใ—ใฆๆŠฝๅ‡บใ™ใ‚‹ใ“ใจใŒใงใใ€ใพใŸ็”ปๅƒใฎๅนณ่กŒ็งปๅ‹•ใ‚„่ผๅบฆๅค‰ๅŒ–ใซๅฏพใ—ใฆใƒญใƒใ‚นใƒˆใชใƒใƒƒใ‚ทใƒฅๅŒ–ใŒใงใใ‚‹ใจ่€ƒใˆใ‚‰ใ‚Œใพใ™ใ€‚

  1. ็”ปๅƒใ‚’็ธฎๅฐใ™ใ‚‹ใ€‚8x8ใ‚ˆใ‚Šใ‚‚ๅคงใใ„ใ‚ตใ‚คใ‚บใซใ™ใ‚‹๏ผˆไพ‹ใˆใฐ32x32ใชใฉ๏ผ‰ใ€‚
  2. ใ‚ฐใƒฌใƒผใ‚นใ‚ฑใƒผใƒซๅŒ–ใ™ใ‚‹ใ€‚
  3. DCTใ™ใ‚‹ใ€‚
  4. ไฝŽๅ‘จๆณขๆ•ฐๆˆๅˆ†ใฎ8x8ใ ใ‘ใ‚’ๅ–ใ‚Šๅ‡บใ™ใ€‚
  5. ็›ดๆตๆˆๅˆ†ใ‚’้™คใ„ใŸไฝŽๅ‘จๆณขๆ•ฐๆˆๅˆ†ใฎๅนณๅ‡ๅ€คใ‚’็ฎ—ๅ‡บใ™ใ‚‹ใ€‚
  6. ๅนณๅ‡ๅ€คใ‚ˆใ‚Šใ‚‚้ซ˜ใ„ใ‹ไฝŽใ„ใ‹ใง2ๅ€คๅŒ–ใ™ใ‚‹ใ€‚
  7. ใƒฉใ‚นใ‚ฟใ‚นใ‚ญใƒฃใƒณ้ †ใชใฉไฝ•ใ‚‰ใ‹ใฎ้ †ใงไธ€ๅˆ—ใซใ—ใ€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็ณปใฎใ‚ขใƒซใ‚ดใƒชใ‚บใƒ ใ‚’ๆœ€่ฟ‘็ŸฅใฃใŸใฎใงใ™ใŒใ€ใ‚ทใƒณใƒ—ใƒซใงใ‹ใคใ„ใ„ใ‚ขใ‚คใƒ‡ใ‚ขใซๅŸบใฅใใ‚ขใƒซใ‚ดใƒชใ‚บใƒ ใงใ‚ใ‚‹ใจๆ€ใ„ใพใ™ใ€‚ๆฏ”่ผƒ็š„ๆžฏใ‚ŒใŸใ‚ขใƒซใ‚ดใƒชใ‚บใƒ ใงใฏใ‚ใ‚‹ใจๆ€ใ„ใพใ™ใŒใ€้ฉๆ้ฉๆ‰€ใงไฝฟใ„ใ“ใชใ›ใ‚‹ใ‚ˆใ†ใซใชใ‚‹ใจใ„ใ„ใงใ™ใญใ€‚

ๅ‚่€ƒ

  1. C. Zauner, "Implementation and Benchmarking of Perceptual Image Hash Functions," Upper Austria University of Applied Sciences, Hagenberg Campus, 2010. โ†ฉ

  2. Recipe1M+: A Dataset for Learning Cross-Modal Embeddings for Cooking Recipes and Food Images - MIT โ†ฉ

  3. ๅฎŸใ‚’่จ€ใ†ใจใ€ใ“ใฎ่ซ–ๆ–‡ใ‚’่ชญใ‚“ใงใ„ใŸใจใใซใ€Œใ‚‚ใฃใจ็ฐกๅ˜ใซ้‡่ค‡ใ‚’่ฆ‹ๅˆ†ใ‘ใ‚‹ๆ–นๆณ•ใŒใ‚ใ‚‹ใฎใงใฏ๏ผŸใ€ใจๆ€ใ„็ซ‹ใฃใŸใฎใŒใ€ๆœฌ่จ˜ไบ‹ใ‚’ๆ›ธใใใฃใ‹ใ‘ใงใ—ใŸ โ†ฉ

81
66
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up

Today's trending articles

Linked from these articles

Comments

No comments

Let's comment your feelings that are more than good

Being held Article posting campaign

81
66

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Login to continue?

Login or Sign up with social account

Login or Sign up with your email address