<jupyter_start><jupyter_text>image processing Average Hash- 이미지를 비교 가능한 해시 값으로 나타낸 것- 해시 함수 MD5, SHA256 등을 이용해 데이터 값을 간단한 해시 값으로 변환할 수 있음- 이미지가 비슷한지 등을 검출할 때는 해시함수를 사용하면 안됨. 해상도 크기 조정, 색조 보정, 압축 형식 변경 등으로 해시값이 달라짐<jupyter_code>from PIL import Image
import numpy as np
def average_hash(fname, size = 16):
    img = Image.open(fname)
    img = img.convert('L') # 1을 지정하면 이진화, RGB, RGBA, CMYK 등의 모드도 지원
    img = img.resize((size, size), Image.ANTIALIAS)
    pixel_data = img.getdata()
    pixels = np.array(pixel_data)
    pixels = pixels.reshape((size, size))
    avg = pixels.mean()
    diff = 1 * (pixels > avg)
    return diff
def np2hash(ahash):
    bhash = []
    for nl in ahash.tolist():
        s1 = [str(i)for i in nl]
        s2 = ''.join(s1)
        i = int(s2, 2)
        bhash.append('%04x' % i)
    return ''.join(bhash)
ahash = average_hash('eiffel_tower.jpeg')
print(ahash)
print(np2hash(ahash))<jupyter_output>7f813f033f0f7f0f7f1ffe7ffe7fff7ffe7fff7f7e3f3e3c0438008000000200<jupyter_text>Caltech 101 데이터- 해밍 거리 : 같은 문자수를 가진 2개의 문자열에서 대응하는 위치에 있는 문자 중 다른 것의 개수    - 256글자의 해시값 중 얼마나 다른지 찾고 이 기반으로 이미지 차이를 구분<jupyter_code>import os, re
search_dir = "./image/101_ObjectCategories/"
cache_dir = "./image/cache_avhash"

if not os.path.exists(cache_dir):
    os.mkdir(cache_dir)
    
def average_hash(fname, size = 16):
    fname2 = fname[len(search_dir):]
    # image cache
    
    cache_file = cache_dir + "/" + fname2.replace('/','_') + '.csv'
    if not os.path.exists(cache_file):
        img = Image.open(fname)
        img = img.convert('L').resize((size, size), Image.ANTIALIAS)
        pixels = np.array(img.getdata()).reshape((size,size))
        avg = pixels.mean()
        px = 1 * (pixels > avg)
        np.savetxt(cache_file, px, fmt="%.0f", delimiter=",")
    else:
        px = np.loadtxt(cache_file, delimiter=",")
    return px

def hamming_dist(a, b):
    aa = a.reshape(1, -1)
    ab = b.reshape(1, -1)
    dist = (aa != ab).sum()
    return dist

def enum_all_files(path):
    for root, dirs, files in os.walk(path):
        for f in files:
            fname = os.path.join(root, f)
            if re.search(r'\.(jpg|jpeg|pnp)$', fname):
                yield fname
                                
def find_image(fname, rate):
    src = average_hash(fname)
    for fname in enum_all_files(search_dir):
        dst = average_hash(fname)
        diff_r = hamming_dist(src, dst) / 256
        if diff_r < rate:
            yield (diff_r, fname)
            
srcfile = search_dir + "/chair/image_0016.jpg"
html = ""
sim = list(find_image(srcfile, 0.25))
sim = sorted(sim, key = lambda x: x[0])
for r, f in sim:
    print(r, ">", f)
    s = '<div style="float:left;"><h3>[ 차이 : ' + str(r) + '-' + os.path.basename(f) + ']</h3>' + \
        '<p><a herf="' + f + '"><img src="' + f + '" width=400>' + '</a></p></div>'
    html += s

html = """<html><head><meta charset="utf8">/head>
       <body><h3> 원래 이미지 </h3><p>
       <img src = '{0}' width=400></p>{1}</body></html>""".format(srcfile, html)
with open("./avgash-search-output.html", "w", encoding="utf-8") as f:
    f.write(html)
print("ok")<jupyter_output>0.0 > ./image/101_ObjectCategories/chair/image_0016.jpg
0.22265625 > ./image/101_ObjectCategories/stop_sign/image_0019.jpg
0.2265625 > ./image/101_ObjectCategories/chair/image_0031.jpg
0.23046875 > ./image/101_ObjectCategories/airplanes/image_0129.jpg
0.234375 > ./image/101_ObjectCategories/umbrella/image_0009.jpg
0.23828125 > ./image/101_ObjectCategories/airplanes/image_0124.jpg
0.24609375 > ./image/101_ObjectCategories/chair/image_0001.jpg
0.24609375 > ./image/101_ObjectCategories/chair/image_0002.jpg
0.24609375 > ./image/101_ObjectCategories/dragonfly/image_0001.jpg
ok<jupyter_text>CNN- 일정한 크기로 리사이즈한 후, 24비트 RGB 형식으로 변환 -> Numpy 배열로 저장<jupyter_code>from PIL import Image
import os, glob
import numpy as np
from sklearn.model_selection import train_test_split

# 분류 대상 카테고리 선택
caltech_dir<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1494832367027981, 'fraction_numerical': 0.05923871943534157, 'mean_word_length': 3.1204569055036346, 'pattern_counts': {'":': 0, '<': 32, '<?xml version=': 0, '>': 45, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '3', 'dir': 'jupyter-structured-clean-dedup', 'id': '447659', 'license': 'MIT', 'n_tokens_mistral': 1877, 'n_tokens_neox': 1856, 'n_words': 349, 'path': 'python/image processing.ipynb', 'repo_name': 'zzsza/TIL', 'size': '3967'}