แ„‚ ๐Ÿ”ต [15 ์ผ์ฐจ] : FUNDAMENTAL 16. ์ด๋ฏธ์ง€ํŒŒ์ผ ๋‹ค๋ฃจ๊ธฐ

๋ฏธ๋ฆฌ ์•Œ์•„๋ณด๊ธฐ

  • pillow
  • OpenCV
  • ์ด๋ฏธ์ง€ ์—ด๊ธฐ, ํŒŒ์ผ ์ •๋ณด ์ถ”์ถœํ•˜๊ธฐ
  • CIFAR-100์—์„œ ํžˆ์Šคํ† ๊ทธ๋žจ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์œ ์‚ฌํ•œ ์ด๋ฏธ์ง€๋ฅผ ๊ณจ๋ผ๋‚ด๊ธฐ

ํ™˜๊ฒฝ ์„ธํŒ…

  1. ํ„ฐ๋ฏธ๋„์—์„œ ์•„๋ž˜์™€ ๊ฐ™์ด ์„ธํŒ…

    $ pip install pillow opencv-python matplotlib    
  2. ํŒŒ์ผ ์ค€๋น„ํ•˜๊ธฐ

    $ mkdir -p ~/aiffel/python_image_proc/data
    $ ln -s ~/data/* ~/aiffel/python_image_proc/data
    $ ls ~/aiffel/python_image_proc/data  # ํŒŒ์ผ ํ™•์ธ
  3. ์‹ค์Šต์šฉ์œผ๋กœ CIFAR-100 ์ด๋ฏธ์ง€ ๋ฐ์ดํ„ฐ์…‹์„ ์‚ฌ์šฉ
    CIFAR-100

๋””์ง€ํ„ธ ์ด๋ฏธ์ง€

  • ๋””์ง€ํ„ธ ํ™”๋ฉด์€ ์ˆ˜๋งŽ์€ ์ ๋“ค๋กœ ์ด๋ฃจ์–ด์ง
  • ์ƒ‰์ƒ์„ ๊ฐ€์ง€๋Š” ์  ํ•˜๋‚˜๋ฅผ ํ™”์†Œ(pixel, picture element)
  • ๊ฐ ํ™”์†Œ๋Š” RGB(Red, Green, Blue) ์„ธ ๊ฐœ์˜ ๋‹จ์ผ ์ƒ‰์˜ ๊ฐ•๋„๋ฅผ ๊ฐ๊ฐ ์กฐ์ ˆํ•˜์—ฌ ์ƒ‰์ƒ์„ ํ‘œํ˜„

    -> ์ด์œ 
    ๋ˆˆ์˜ ๋ง๋ง‰์— ์žˆ๋Š” ์‹œ์„ธํฌ๊ฐ€ ์ธ๊ฐ„์˜ ๊ฒฝ์šฐ ๋Œ€๋ถ€๋ถ„ ์„ธ ๊ฐ€์ง€๋กœ

๋ž˜์Šคํ„ฐ or ๋น„ํŠธ๋งต

  • ๋นจ๊ฐ•, ์ดˆ๋ก, ํŒŒ๋ž‘ ์„ธ ๊ฐ€์ง€ ์ƒ‰์˜ ๊ฐ•๋„๋กœ ํ‘œํ˜„๋˜๋Š” ์  ํ•˜๋‚˜ํ•˜๋‚˜์˜ ์ƒ‰์ƒ ๊ฐ’์„ ์ €์žฅ
  • ์ด๋ฅผ ๋ž˜์Šคํ„ฐ(raster) ๋˜๋Š” ๋น„ํŠธ๋งต(bitmap) ๋ฐฉ์‹์˜ ์ด๋ฏธ์ง€
  • ํ•œ ์ ๋งˆ๋‹ค ๊ฐ ์ƒ‰์ƒ๋ณ„๋กœ 8๋น„ํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ 0~255 ์‚ฌ์ด์˜ ๊ฐ’(2^8 = 256)์œผ๋กœ ํ•ด๋‹น ์ƒ‰์˜ ๊ฐ๋„๋ฅผ ํ‘œ์‹œ

๋ฒกํ„ฐ

  • ๋ฒกํ„ฐ(vector) ๋ฐฉ์‹์˜ ์ด๋ฏธ์ง€๋Š” ์ƒ๋Œ€์ ์ธ ์ ๊ณผ ์„ ์˜ ์œ„์น˜๋ฅผ ๋ฐฉ์ •์‹์œผ๋กœ์จ ๊ธฐ๋ก
  • ํ™•๋Œ€ ๋ฐ ์ถ•์†Œ์— ๋”ฐ๋ผ ๋””์ง€ํ„ธ ํ™”๋ฉด์˜ ๊ฐ ํ™”์†Œ์— ์–ด๋–ป๊ฒŒ ํ‘œํ˜„๋ ์ง€๋ฅผ ์žฌ๊ณ„์‚ฐํ•˜๊ธฐ์— ๊นจ์ง์ด ์—†์Œ

jpg

  • ๊ทผ์ฒ˜์— ์žˆ๋Š” ํ™”์†Œ๋“ค์„ ๋ฌถ์–ด, ๋น„์Šทํ•œ ์ƒ‰๋“ค์„ ๋ญ‰๋šฑ๊ทธ๋ฆฌ๋Š” ๋ฐฉ์‹์œผ๋กœ ์ด๋ฏธ์ง€๋ฅผ ์••์ถ•
  • ์ƒ‰์ƒ ์ •๋ณด์˜ ์†์‹ค, ์ €์žฅํ•  ๋•Œ ์••์ถ•๋ฅ ์„ ๋†’์ผ ๋•Œ
  • ๋‹ค์‹œ ์ €์žฅํ•˜๋Š” ๋“ฑ ์žฌ์••์ถ• ์‹œ
  • ๋””์ง€ํ„ธ ํ’ํ™”๋ผ๊ณ  ๋ถˆ๋ฆฌ๋Š” ์ƒ‰์ƒ์ด ์ง€์ €๋ถ„ํ•ด์ง€๋Š” ํ˜„์ƒ

png

  • ์Šคํฌ๋ฆฐ์ƒท ๋“ฑ์— ๋งŽ์ด ์‚ฌ์šฉ๋˜๋Š” PNG ์ด๋ฏธ์ง€ ํ˜•์‹
  • ์ƒ‰์ƒ์˜ ์†์‹ค ์—†์ด ์ด๋ฏธ์ง€๋ฅผ ์••์ถ•
  • ์ด๋ฏธ์ง€์— ์‚ฌ์šฉ๋œ ์ƒ‰์ƒ์„ ๋ฏธ๋ฆฌ ์ •์˜ํ•ด๋‘๊ณ  ๊ทธ๋ฅผ ์ฐธ์กฐํ•˜๋Š” ํŒ”๋ ˆํŠธ ๋ฐฉ์‹์„ ์‚ฌ์šฉ
  • ์‚ฌ์šฉ๋œ ์ƒ‰์ƒ์ด ์ ์€ ๋‹จ์ˆœํ•œ ์ด๋ฏธ์ง€์˜ ๊ฒฝ์šฐ ๋™์ผํ•œ ํ•ด์ƒ๋„์˜ JPEG ํŒŒ์ผ๋ณด๋‹ค๋„ ์šฉ๋Ÿ‰์ด ์ž‘์Œ
  • ์‚ฌ์ง„๊ณผ ๊ฐ™์ด ์ด๋ฏธ์ง€์— ์‚ฌ์šฉ๋œ ์ƒ‰์ƒ์ด ๋งŽ์•„์ง€๋ฉด JPEG ํŒŒ์ผ๋ณด๋‹ค ์‰ฝ๊ฒŒ ๋” ๋งŽ์€ ์šฉ๋Ÿ‰์„ ์ฐจ์ง€

GIF

  • ์›€์งค๋กœ ์ต์ˆ™
  • ์ด๋ฏธ์ง€ ๋‚ด์— ์—ฌ๋Ÿฌ ํ”„๋ ˆ์ž„์„ ๋‘์–ด ์ด๋ฅผ ์›€์ง์ด๊ฒŒ
  • ์ƒ‰์ƒ ์ •๋ณด๋ฅผ ์†์‹ค ์—†์ด ์ €์žฅ
  • 256๊ฐœ์˜ ์ƒ‰์ƒ๋งŒ ๊ธฐ์–ตํ•  ์ˆ˜ ์žˆ๋Š” ํŒ”๋ ˆํŠธ ๋ฐฉ์‹์œผ๋กœ ์ œํ•œ

์ด๋ฏธ์ง€ ๋‹ค๋ฃจ๊ธฐ (Pillow ์‚ฌ์šฉ๋ฒ•)

  • ์ „์‹ 
    - PIL(Python Image Library)์ด๋ผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
    • Pillow๊ฐ€ ์ด์–ด๋ฐ›์•„ ํ˜„์žฌ๊นŒ์ง€๋„ ์ง€์†์ ์œผ๋กœ ์‚ฌ์šฉ
    • Pillow๋Š” Numpy์™€ ๊ฒฐํ•ฉํ•˜์—ฌ ๊ฐ„ํŽธํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋„๊ตฌ
  • ๋””์ง€ํ„ธ ์ด๋ฏธ์ง€
    - ์ด๋ฏธ์ง€๋Š” ๋ฐฐ์—ด ํ˜•ํƒœ์˜ ๋ฐ์ดํ„ฐ
    • ์˜ˆ
      • ๊ฐ€๋กœ ์„ธ๋กœ ๊ฐ 32ํ”ฝ์…€์— RGB ์„ธ ๊ฐ€์ง€ ์ƒ‰์ƒ ์ฑ„๋„
        • Numpy๋กœ [32, 32, 3] ์ฐจ์›์˜ ๋ฐฐ์—ด์„ ์ƒ์„ฑ
        • ๋ฐ์ดํ„ฐ ํƒ€์ž…์„ uint8(๊ฐ ๊ฐ’์ด ๋ถ€ํ˜ธ๊ฐ€ ์—†๋Š”(unsigned) 8๋น„ํŠธ ์ •์ˆ˜(integer))
        • 0~255(2์˜ 8์Šน = 256) ์‚ฌ์ด์˜ ๊ฐ’

          data = np.zeros([32,32,3],dtype=np.unit8)
          => ๋ฐ์ดํ„ฐ๋Š” ๋„˜ํŒŒ์ด ์ œ๋กœ์— 32,32,์‹ธ์ด์ฆˆ์˜ 3์ƒ‰์ƒ์— dtype์ด ๋„˜ํŒŒ์ด

numpy PIL ํ˜ธ์ถœ

import numpy as np
from PIL import Image

๋””์ง€ํ„ธ ์ด๋ฏธ์ง€ ์ดˆ๊ธฐํ™”

data = np.zeros([32, 32, 3], dtype=np.uint8) # ๊ฐ€๋กœ, ์„ธ๋กœํฌ๊ธฐ, RGB 

ํ•œ๋ฒˆ์— ํ‘œ์‹œ

import numpy as np       
from PIL import Image

data = np.zeros([32, 32, 3], dtype=np.uint8) 
image = Image.fromarray(data, 'RGB')
image

data[:, :] = [255, 0, 0]
image = Image.fromarray(data, 'RGB')
image

์˜ˆ

  • width์™€ height๋ฅผ ์ถœ๋ ฅํ•˜๊ณ , .save()๋ฅผ ์ด์šฉํ•˜์—ฌ jpg ํŒŒ์ผ ํฌ๋งท์œผ๋กœ ์ €์žฅ
import numpy as np
from PIL import Image
data = np.zeros([32,32,3], dtype=np.unit8)
image = Image.fromarry(data, 'RGB')
show(image)

์ด๋ฏธ์ง€ ํฌ๋ฉง ๋ณ€ํ™˜

img = Image.open(image_path)
new_image_path = os.getenv('HOME')+'jpg_pillow_practice.jpg'
img = img.convert('RGB')
img.save(new_image_path)

์ด๋ฏธ์ง€ ์ €์žฅ .save()

resized_image = img.resize((100,200))

์ด๋ฏธ์ง€ ํฌ๊ธฐ ์กฐ์ ˆ .resize()

resized_image = img.resize((100,200))

์ด๋ฏธ์ง€ ์ž˜๋ผ๋‚ด๊ธฐ .crop()

box = (300, 100, 600, 400)
region = img.crop(box)

์ด๋ฏธ์ง€ ํ™•์žฅ์ž ์ž„์˜๋กœ ๋ณ€๊ฒฝ

# ์ด๋ฏธ์ง€ ํ™•์žฅ์ž๋ฅผ ์ž„์˜๋กœ wpg๋กœ ๋ฐ”๊ฟˆ wpg = w png
image_path = './python_image_proc/data/pillow_practice.wpg'

# ์ด๋ฏธ์ง€ ์—ด๊ธฐ
img = Image.open(image_path)
img

Pillow๋ฅผ ํ™œ์šฉํ•œ ๋ฐ์ดํ„ฐ ์ „์ฒ˜๋ฆฌ

CIFAR ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„ ๊ฐœ๋ณ„ ์ด๋ฏธ์ง€ ํŒŒ์ผ๋กœ ์ถ”์ถœ

import os
import pickle
from PIL import Image

dir_path = './python_image_proc/data/cifar-100-python' # ์—ฌ๊ธฐ์— ์žˆ๋Š” ๊ฒƒ์˜
train_file_path = os.path.join(dir_path, 'train')      # train์— ๋“ค์–ด๊ฐ€์„œ

with open(train_file_path, 'rb') as f:
    train = pickle.load(f, encoding='bytes')

print(type(train))
print(train)   

๋ชจ๋“ˆ pickle ํ™œ์šฉ๋ฒ•

  • pickle.dump(๊ฐ์ฒด, ํŒŒ์ผ) ๋กœ ์ €์žฅํ•˜๊ณ 
  • pickle.load(ํŒŒ์ผ) ๋กœ ๋กœ๋”ฉํ•ฉ๋‹ˆ๋‹ค
  • ํŒŒ์ด์ฌ์˜ ๋ณ€์ˆ˜ ํ˜น์€ ํด๋ž˜์Šค ์ธ์Šคํ„ด์Šค๋ฅผ binary ํ˜•ํƒœ๋กœ ์ €์žฅํ•˜๋Š” ํŒจํ‚ค์ง€
import pickle
my_list = ['a','b','c']
 
## Save pickle
with open("data.pickle","wb") as fw:
    pickle.dump(my_list, fw)
 
## Load pickle
with open("data.pickle","rb") as fr:
    data = pickle.load(fr)
print(data)
#['a', 'b', 'c']

๊ทผ๋ฐ wb๋ž‘ rb๋Š” ๋ญ๋ƒ

  • pickle.dump(object, filepath) ๋ฅผ ์ด์šฉํ•˜์—ฌ ๋ณ€์ˆ˜๋ฅผ ์ €์žฅ
  • pickle.load(filepath) ๋ฅผ ์ด์šฉํ•˜์—ฌ ์ €์žฅ๋œ ๋ณ€์ˆ˜๋ฅผ ์ฝ๊ธฐ
  • file open ์‹œ mode ๋ฅผ โ€˜wbโ€™ ์™€ โ€˜rbโ€™ ๋ฅผ ์ž…๋ ฅ
  • 'wb ๋Š” write binary, rb ๋Š” read binary ๋ฅผ ์˜๋ฏธ

๋‹ค์‹œ

import os
import pickle
from PIL import Image

dir_path = './python_image_proc/data/cifar-100-python' # ์—ฌ๊ธฐ์— ์žˆ๋Š” ๊ฒƒ์˜
train_file_path = os.path.join(dir_path, 'train')      # train์— ๋“ค์–ด๊ฐ€์„œ

with open(train_file_path, 'rb') as f:
    train = pickle.load(f, encoding='bytes')

print(type(train))
print(train)   

<class 'dict'>
{b'filenames': [b'bos_ta........, 72, 69, 67]], dtype=uint8)}

๊ฒฐ๊ณผ๋Š” ๋„ˆ๋ฌด ๋งŽ๋‹ค...
์ผ๋‹จ ๋ฐ์ดํ„ฐ๋ฅผ ์ œ๊ณตํ•œ ์‚ฌ๋žŒ์˜ ์„ค๋ช…์„ ๋ณด๋ฉด ๋”•์…”๋„ˆ๋ฆฌ ํŒŒ์ผ๋กœ ๋˜์–ด ์žˆ๋‹ค๋‹ˆ
์–ด๋–ค ํ‚ค๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธํ•ด๋ณด์ž

train.keys()

dict_keys([b'filenames', b'batch_label', b'fine_labels', b'coarse_labels', b'data'])

๊ฐ ํ‚ค๋“ค์ด ๋ฌธ์ž์—ด(str)์ด ์•„๋‹Œ b๋กœ ์‹œ์ž‘ํ•˜๋Š” bytes๋กœ ๋˜์–ด์žˆ๋‹ค!

์ผ๋‹จ ์ฒซ๋ฒˆ์งธ ์ •๋ณด์ธ ํŒŒ์ผ๋ช…(b'filenames')์˜ ํƒ€์ž…์„ ํ™•์ธํ•ด๋ณด์ž

type(train[b'filenames'])

list

๋ฆฌ์ŠคํŠธ๋„ค.
์•ž 5๊ฐœ๋งŒ ํ™•์ธํ•ด๋ณด์ž

train[b'filenames'][0:5]

[b'bos_taurus_s_000507.png',
b'stegosaurus_s_000125.png',
b'mcintosh_s_000643.png',
b'altar_boy_s_001435.png',
b'cichlid_s_000031.png']

๋ฐ์ดํ„ฐ ์„ค๋ช…์„ ๋ณด๋ฉด

Data: a 10000x3072 numpy array of uint8s. Each row of the array stores a 32x32 colour image. The first 1024 entries contain the red channel values, the next 1024 the green, and the final 1024 the blue. The image is stored in row-major order, so that the first 32 entries of the array are the red channel values of the first row of the image.

๋”•์…”๋„ˆ๋ฆฌ b'data'์— ์žˆ๋ฐ, ๊บผ๋‚ด๋ณด์ž

train[b'data'][0:5]

array([[255, 255, 255, ..., 10, 59, 79],
[255, 253, 253, ..., 253, 253, 255],
[250, 248, 247, ..., 194, 207, 228],
[124, 131, 135, ..., 232, 236, 231],
[ 43, 32, 87, ..., 60, 29, 37]], dtype=uint8)

numpy ๋ฐฐ์—ด์ด ๋‚˜์™”๋„ค..
ํ˜•ํƒœ๋ฅผ ๋ณด์ž

train[b'data'][0].shape

(3072,)

3072๋ผ๋Š” ์ˆซ์ž๋Š” ๋นจ๊ฐ• ์ดˆ๋ก ํŒŒ๋ž‘ 3์ฑ„๋„ X 1024(=32 * 32)์”ฉ ๊ฐ ํ™”์†Œ์— ํ•ด๋‹นํ•˜๋Š” ๊ฒƒ

  • Numpy ๋ฐฐ์—ด์„ ์ž˜ reshapeํ•˜๋ฉด ์ด๋ฏธ์ง€ ํŒŒ์ผ ์›๋ณธ์ด ๋ณต๊ตฌ๋จ
  • ์ฃผ์˜์ 
    - 3072๋ฐ”์ดํŠธ์˜ ์ด๋ฏธ์ง€ ๋ฐ์ดํ„ฐ๋Š” ์•ž 1024๋ฐ”์ดํŠธ๋Š” ๋นจ๊ฐ•(R), ๊ทธ๋‹ค์Œ 1024๋Š” ๋…น์ƒ‰(G), ๋งˆ์ง€๋ง‰ 1024๋Š” ํŒŒ๋ž‘(B)
    • ๊ทธ๋ƒฅ ๋ชจ์–‘๋งŒ ๋งž์ถ”์–ด reshapeํ•˜๋ฉด ์•ˆ๋จ
    • 1024๋ฅผ 32X32์— ์ฑ„์šฐ๋Š” ๊ฒƒ์„ 3๋ฒˆ ๋ฐ˜๋ณตํ•˜๋Š” ๋ฐฉ์‹์˜ reshape
    • ์•ž์„  ์ฐจ์›๋ถ€ํ„ฐ ๋ฐ์ดํ„ฐ๋ฅผ ์ฑ„์šฐ๋Š” ๋ฐฉ์‹์˜ reshape๋ฅผ ์œ„ํ•ด np.reshape์—๋Š” order๋ผ๋Š” ์ธ์ž
    • ์ด ์ธ์ž๋ฅผ Fํ˜ธ ์ฃผ๋ฉด ์›ํ•˜๋Š” ํ˜•ํƒœ๋กœ ์ง„ํ–‰
image_data = train[b'data'][0].reshape([32, 32, 3], order='F')   # order๋ฅผ ์ฃผ์˜ํ•˜์„ธ์š”!!
image = Image.fromarray(image_data)    # Pillow๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Numpy ๋ฐฐ์—ด์„ Image๊ฐ์ฒด๋กœ ๋งŒ๋“ค์–ด์„œ
image    # ํ™”๋ฉด์— ๋„์›Œ ๋ด…์‹œ๋‹ค!!

x์ถ•๊ณผ y์ถ•์ด ๋’ค์ง‘์–ด์„œ ๋‚˜์˜ด -> ์ถ•์„ ๋ฐ”๊ฟ”์ฃผ๋Š” ์ž‘์—…์ด ํ•„์š”

์ด๋ฏธ์ง€ ์ถ• ๋ฐ”๊พธ๊ธฐ

  • np.swapaxes(0, 1)
image_data = image_data.swapaxes(0, 1)
image = Image.fromarray(image_data)
image

์ง€๊ธˆ๊นŒ์ง€ ์ข…ํ•ฉ

import os
import pickle
from PIL import Image
import numpy
from tqdm import tqdm

dir_path = './python_image_proc/data/cifar-100-python'
train_file_path = os.path.join(dir_path, 'train')

# image๋ฅผ ์ €์žฅํ•  cifar-100-python์˜ ํ•˜์œ„ ๋””๋ ‰ํ† ๋ฆฌ(images)๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. 
images_dir_path = './python_image_proc/cifar-images'
if not os.path.exists(images_dir_path):
    os.mkdir(images_dir_path)  # images ๋””๋ ‰ํ† ๋ฆฌ ์ƒ์„ฑ

# 32X32์˜ ์ด๋ฏธ์ง€ ํŒŒ์ผ 50000๊ฐœ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. 
with open(train_file_path, 'rb') as f:
    train = pickle.load(f, encoding='bytes')
    for i in tqdm(range(len(train[b'filenames']))):
        filename = train[b'filenames'][i].decode()
        data = train[b'data'][i].reshape([32, 32, 3], order='F')
        image = Image.fromarray(data.swapaxes(0, 1))
        image.save(os.path.join(images_dir_path, filename))

100%|โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ| 50000/50000 [00:24<00:00, 2011.90it/s]

OpenCV

  • ์˜์ƒ ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•œ ๋‹ค์–‘ํ•œ ๊ณ ๊ธ‰ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„
    Changing Colorspaces
  • OpenCV์—์„œ๋Š” RGB๊ฐ€ ์•„๋‹Œ BGR์ˆœ์„œ

    ์ฝ”๋“œ๋ฅผ ํ•œ๋ฒˆ ์‚ดํŽด๋ณด์„ธ์š”.

    import os
    import cv2 as cv
    import numpy as np
    from  matplotlib import pyplot as plt
    %matplotlib inline

img_path = './python_image_proc/data/cv_practice.png'
img = cv.imread(img_path)

Convert BGR to HSV

hsv = cv.cvtColor(img, cv.COLOR_BGR2HSV)

define range of blue color in HSV

lower_blue = np.array([100,100,100])
upper_blue = np.array([130,255,255])

Threshold the HSV image to get only blue colors

mask = cv.inRange(hsv, lower_blue, upper_blue)

Bitwise-AND mask and original image

res = cv.bitwise_and(img, img, mask=mask)

plt.imshow(cv.cvtColor(img, cv.COLOR_BGR2RGB))
plt.show()
plt.imshow(cv.cvtColor(mask, cv.COLOR_BGR2RGB))
plt.show()
plt.imshow(cv.cvtColor(res, cv.COLOR_BGR2RGB))
plt.show()


>> ![](https://media.vlpt.us/images/pasianus/post/c6fbdf3d-ff34-495e-af1d-e1da89627f03/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202022-01-17%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2010.27.17.png)

### ๋ชจ๋“ˆ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ
```python
import cv2 as cv
import numpy as np

OpenCV๋Š” pip ์„ค์น˜์‹œ opencv-python
import์‹œ์—๋Š” cv2
OpenCV์™€ Numpy๋Š” ์„ธ๋šœ

.imrea()

img_path = './python_image_proc/data/cv_practice.png'
img = cv.imread(img_path)

ํŒŒ์ผ๋กœ๋ถ€ํ„ฐ ์ด๋ฏธ์ง€๋ฅผ ์ฝ์–ด์™€ ๋ฐ˜ํ™˜ํ•ด์ฃผ๋Š” ํ•จ์ˆ˜

OpenCV ๊ณต์‹ ๋ฌธ์„œํ™” ์‚ฌ์ดํŠธ

.cvtColor(๋ณ€์ˆ˜, cv.COLOR_BGR2HSV)

# Convert BGR to HSV
hsv = cv.cvtColor(img, cv.COLOR_BGR2HSV)

OpenCV: Color Space Conversions

cvtColor์€ ์ปฌ๋Ÿฌ ์ŠคํŽ˜์ด์Šค ๋ณ€ํ™˜(convert)์„ ์œ„ํ•œ ํ•จ์ˆ˜

์ถ”์ถœ์„ ์œ„ํ•œ ๊ธฐ์ค€์ƒ‰ ์ •์˜

# define range of blue color in HSV
lower_blue = np.array([100,100,100])
upper_blue = np.array([130,255,255])

์›ํ•˜๋Š” ์ƒ‰์„ ์ถ”์ถœ

  • HSV ์ƒ‰ ๊ณต๊ฐ„์—์„œ ์ƒ‰์ƒ(Hue) ๊ฐ’ 110~130 ์‚ฌ์ด, ์ฑ„๋„(Saturation) ๋ฐ ๋ช…๋„(Value) ๊ฐ’ 50~255 ์‚ฌ์ด์˜ ์ƒ‰๋“ค์„ ํŒŒ๋ž€์ƒ‰์ด๋ผ๊ณ  ์ •์˜

HSV์— ๋Œ€ํ•ด ์ดํ•ด๊ฐ€ ํ•„์š”

cfcf

  1. RGB ์ด๋ฏธ์ง€๋ฅผ ์ž…๋ ฅ๋ฐ›์•„ HSV ์ด๋ฏธ์ง€๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค.
  2. ์ƒ‰์ƒ์˜ ๋ฒ”์œ„์— ๋”ฐ๋ผ ํŠน์ • ์ƒ‰์ƒ์˜ ๊ฐ์ฒด๋ฅผ ์ถ”์ถœํ•˜๋Š” ๋งˆ์Šคํฌ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.
  3. ์ƒ์„ฑํ•œ ๋งˆ์Šคํฌ์— ๋”ฐ๋ผ ์ด๋ฏธ์ง€๋ฅผ ๊ณ„์‚ฐํ•˜์—ฌ ํŠน์ •ํ•œ ์ƒ‰์ƒ์˜ ๊ฐ์ฒด๋งŒ ์ถ”์ถœ๋˜๋Š” ๊ฒฐ๊ณผ ์ด๋ฏธ์ง€๋ฅผ ๋งŒ๋“ ๋‹ค.

์ถ”์ถœํ•œ ๊ธฐ์ค€์ƒ‰์œผ๋กœ ๋งˆ์Šคํฌ ์ƒ์„ฑ .inRange()

# Threshold the HSV image to get only blue colors
mask = cv.inRange(hsv, lower_blue, upper_blue)
  • img ๋ฅผ ๋ณ€ํ™˜ํ•œ hsv์—๋‹ค๊ฐ€ ์ด ๊ธฐ์ค€๋“ค(lower_blue, upper_blue)๋ฅผ ์ ์šฉ
  • ํ•ด๋‹นํ•˜๋Š” ํ”ฝ์…€๋“ค์—๋Š” 1, ๊ทธ๋ ‡์ง€ ์•Š์€ ํ”ฝ์…€๋“ค์—๋Š” 0์„ ์ฐ์–ด๋†“์€ ๋ฐฐ์—ด์„ ๋ฐ˜ํ™˜

๊ฐ€๋กœ 400, ์„ธ๋กœ 300 ํ”ฝ์…€์งœ๋ฆฌ ์ด๋ฏธ์ง€๋ฅผ ๋ฐ›์•˜์—ˆ๋‹ค๋ฉด, img๊ณผ hsv๋Š” ๊ฐ๊ฐ ํ”ฝ์…€ ๋‹น BGR, HSV ์„ธ ๊ฐœ์˜ ์ƒ‰์ƒ ์ฑ„๋„๋ณ„ ๊ฐ’์„ ๊ฐ€์งˆ ํ…Œ๊ธฐ ๋•Œ๋ฌธ์—, 400 300 3์˜ ํฌ๊ธฐ๋ฅผ ๊ฐ–๋Š” ๋ฐฐ์—ด์ด์—ˆ๊ณ , mask๋Š” ํ”ฝ์…€๋งˆ๋‹ค 1 ๋˜๋Š” 0๋งŒ์„ ๊ฐ’์œผ๋กœ ๊ฐ€์กŒ๊ธฐ์— 400 300 ( 1)์˜ ํฌ๊ธฐ

์™ผ์ชฝ์ด original frame์œผ๋กœ mask๋ฅผ ๋งŒ๋“  ๋’ค 1์„ ํฐ์ƒ‰์œผ๋กœ, 0์„ ๊ฒ€์ •์œผ๋กœ ํ‘œ์‹œํ•œ๋‹ค๋ฉด, ์œ„ ์ด๋ฏธ์ง€์˜ ๊ฐ€์šด๋ฐ์— ์žˆ๋Š” mask image์™€ ๋™์ผ

.bitwise_and() ์ด๋ฏธ์ง€ ๋‘์žฅ์˜ AND ์—ฐ์‚ฐ

์ด๋ฏธ์ง€ ๋‘ ์žฅ์„ ๋ฐ›์•„์„œ AND ๋น„ํŠธ ์—ฐ์‚ฐ์„ ํ•œ๋‹ค๋Š” ๊ฑด๋ฐ, ์šฐ๋ฆฌ๋Š” ์ด ๊ธฐ๋Šฅ์ด ํ•„์š”ํ•œ ๊ฒŒ ์•„๋‹ˆ๋‹ˆ ๋‘ ์žฅ ๋‹ค ๊ฐ™์€ ์ด๋ฏธ์ง€(img, img)๋ฅผ ๋„ฃ์–ด์„œ ๊ฒฐ๊ตญ ๋™์ผํ•œ ์ด๋ฏธ์ง€๊ฐ€ ๋‚˜์˜ค๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. ๋Œ€์‹  ์ค‘์š”ํ•œ mask๋ฅผ ๊ฐ™์ด ๋„ฃ์–ด์ค˜์„œ, ํ•ด๋‹น ์˜์—ญ๋งŒ ๋”ฐ์˜ค๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ์˜จ ์˜์—ญ์€ ์œ„ ๊ณต์‹ ๋ฌธ์„œ ํŽ˜์ด์ง€์˜ ํ•จ์ˆ˜ ์„ค๋ช…์— ๋”ฐ๋ผ dst๊ฐ€ ์ฃผ์–ด์ง„๋‹ค๋ฉด ๊ทธ ์œ„์—, ์•„๋‹ˆ๋ฉด ์ƒˆ๋กœ ๋นˆ ๊ฒ€์ •์ƒ‰ ์˜์—ญ ์œ„์— ์ด๋ฏธ์ง€๋ฅผ ๋งŒ๋“ค๊ณ  ๋ฐ˜ํ™˜

์ด๋ฏธ์ง€ ๊ฐ์ฒด์˜ ์ปฌ๋Ÿฌ๋ณ€ํ™˜ cvtColor(๋ณ€์ˆ˜, cv.COLOR_BGR2RGB)

plt.imshow(cv.cvtColor(img, cv.COLOR_BGR2RGB))
plt.show()
plt.imshow(cv.cvtColor(mask, cv.COLOR_BGR2RGB))
plt.show()
plt.imshow(cv.cvtColor(res, cv.COLOR_BGR2RGB))
plt.show()

๋ฐ›์•„์˜จ ์ด๋ฏธ์ง€ img, ํŒŒ๋ž€์ƒ‰์ธ ์˜์—ญ๋งŒ ๊ณจ๋ผ๋‚ธ ๋งˆ์Šคํฌ mask, ๊ทธ๋ฆฌ๊ณ  ์ด๋ฏธ์ง€์— ๋งˆ์Šคํฌ๋ฅผ ์ ์šฉํ•œ ๊ฒฐ๊ณผ res๋ฅผ ํ‘œ์‹œ

cfcf. plt ๋กœ ๋ณด์—ฌ์ฃผ์ง€ ์•Š๊ณ  cv ๋กœ ์ด๋ฏธ์ง€๋ฅผ ๋„์šฐ๋Š” ๋ฐฉ๋ฒ•

  • cv.imshow(res) = PIL.Image.show(), plt.imshow()

๋น„์Šทํ•œ ์ด๋ฏธ์ง€ ์ฐพ์•„๋‚ด๊ธฐ

์ด๋ฏธ์ง€์—์„œ ์ƒ‰์ƒ ํžˆ์Šคํ† ๊ทธ๋žจ์„ ์ถ”์ถœ

cfcf ํžˆ์Šคํ† ๊ทธ๋žจ

  • ์ด๋ฏธ์ง€์—์„œ ํ”ฝ์…€ ๋ณ„ ์ƒ‰์ƒ ๊ฐ’์˜ ๋ถ„ํฌ
  • ํžˆ์Šคํ† ๊ทธ๋žจ์„ ํ†ตํ•ด, ๊ฐ ์ด๋ฏธ์ง€์˜ ์ƒ‰์ƒ ๋ถ„ํฌ๋ฅผ ๋น„๊ตํ•˜์—ฌ ์„œ๋กœ ์œ ์‚ฌํ•œ ์ด๋ฏธ์ง€๋ฅผ ํŒ๋‹จํ•˜๋Š” ์ฒ™๋„๋กœ ์‚ฌ์šฉ

์œ„์˜ ์˜ˆ์‹œ๋Š” ์ด๋ฏธ์ง€๋ฅผ ํ‘๋ฐฑ์œผ๋กœ ๋ณ€ํ™˜ํ–ˆ์„ ๋•Œ ๋ฐ๊ธฐ์— ๋”ฐ๋ฅธ ํžˆ์Šคํ† ๊ทธ๋žจ
์šฐ๋ฆฌ๋Š” RGB ๊ฐ ์ฑ„๋„๋ณ„ ๋ถ„ํฌ๋ฅผ ์‚ฌ์šฉ
0~255 ์‚ฌ์ด ๊ฐ ๊ฐ’์— ํ•ด๋‹นํ•˜๋Š” ํ”ฝ์…€์˜ ๊ฐœ์ˆ˜๋ฅผ ์ผ์ผ์ด ์ €์žฅํ•˜๊ธฐ์—๋Š” ๊ณ„์‚ฐ๋Ÿ‰์ด ๋งŽ์•„์ง€๋ฏ€๋กœ, ๋‹จ์ˆœํ™”์˜ ์ธก๋ฉด์—์„œ ์ด๋ฅผ 4๊ฐœ ๊ตฌ๊ฐ„(0~63, 64~127, 128~191, 192~255)๋กœ ๋‚˜๋ˆ„์–ด ํ”ฝ์…€ ์ˆ˜ ์„ธ๊ธฐ

  • ํžˆ์Šคํ† ๊ทธ๋žจ์„ ์‹ค์ œ๋กœ ํ™”๋ฉด์— ํ‘œ์‹œํ•˜๊ธฐ ์œ„ํ•ด matplotlib๋„ ์„ค์น˜
  • OpenCV๋ฅผ ํŒŒ์ด์ฌ์—์„œ ๋ถˆ๋Ÿฌ ์“ธ ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ํŒจํ‚ค์ง€ opencv-python ์„ค์น˜

$ pip install opencv-python matplotlib

import os
import pickle
import cv2
import numpy as np
from matplotlib import pyplot as plt
from tqdm import tqdm
from PIL import Image

# ์ „์ฒ˜๋ฆฌ ์‹œ ์ƒ์„ฑํ–ˆ๋˜ ๋””๋ ‰ํ† ๋ฆฌ ๊ตฌ์กฐ
dir_path = './python_image_proc/'
train_file_path = os.path.join(dir_path, 'train')
images_dir_path = os.path.join(dir_path, 'cifar-images')
# ํŒŒ์ผ๋ช…์„ ์ธ์ž๋กœ ๋ฐ›์•„ ํ•ด๋‹น ์ด๋ฏธ์ง€ ํŒŒ์ผ๊ณผ ํžˆ์Šคํ† ๊ทธ๋žจ์„ ์ถœ๋ ฅํ•ด ์ฃผ๋Š” ํ•จ์ˆ˜
def draw_color_histogram_from_image(file_name):
    image_path = os.path.join(images_dir_path, file_name)
    # ์ด๋ฏธ์ง€ ์—ด๊ธฐ
    img = Image.open(image_path)
    cv_image = cv2.imread(image_path)

    # Image์™€ Histogram ๊ทธ๋ ค๋ณด๊ธฐ
    f=plt.figure(figsize=(10,3))
    im1 = f.add_subplot(1,2,1)
    im1.imshow(img)
    im1.set_title("Image")

    im2 = f.add_subplot(1,2,2)
    color = ('b','g','r')
    for i,col in enumerate(color):
        # image์—์„œ i๋ฒˆ์งธ ์ฑ„๋„์˜ ํžˆ์Šคํ† ๊ทธ๋žจ์„ ๋ฝ‘์•„์„œ(0:blue, 1:green, 2:red)
        histr = cv2.calcHist([cv_image],[i],None,[256],[0,256])   
        im2.plot(histr,color = col)   # ๊ทธ๋ž˜ํ”„๋ฅผ ๊ทธ๋ฆด ๋•Œ ์ฑ„๋„ ์ƒ‰์ƒ๊ณผ ๋งž์ถฐ์„œ ๊ทธ๋ฆฝ๋‹ˆ๋‹ค.
    im2.set_title("Histogram")
draw_color_histogram_from_image('adriatic_s_001807.png')

์„œ๋กœ ๋น„๊ตํ•˜๋Š” ๊ธฐ๋Šฅ

์„ค๊ณ„ ์‹ค์Šต

STEP1. ์•„์ด๋””์–ด ๊ฐœ์š”

์šฐ๋ฆฌ๊ฐ€ ๋งŒ๋“ค ๊ฒฐ๊ณผ๋ฌผ์€ histogram_search.py๋ผ๋Š” Python ํŒŒ์ผ์ด๊ณ , ์ด ํŒŒ์ผ์€ ์ด๋ฏธ์ง€ ํŒŒ์ผ ๊ฒฝ๋กœ ํ•˜๋‚˜๋ฅผ ๋ช…๋ น์ค„์—์„œ ์ž…๋ ฅ์œผ๋กœ ๋ฐ›์•„, ๊ฒ€์ƒ‰ ๋Œ€์ƒ ์ด๋ฏธ์ง€๋“ค ์ค‘ ๋น„์Šทํ•œ ์ด๋ฏธ์ง€๋“ค์„ ๊ณจ๋ผ ํ™”๋ฉด์— ํ‘œ์‹œํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰

ํ•ต์‹ฌ์€
1. ์ปดํ“จํ„ฐ์—๊ฒŒ ๋น„์Šทํ•œ ์ด๋ฏธ์ง€๋ผ๋Š” ๊ฐœ๋…์„ ์–ด๋–ป๊ฒŒ ๊ตฌํ˜„ํ•˜๋Š๋ƒ

  • ํžˆ์Šคํ† ๊ทธ๋žจ์œผ๋กœ ๋น„๊ต
    -> OpenCV์—์„œ cv2.compareHist() ๋ผ๋Š” ํ•จ์ˆ˜ ์ œ๊ณต
  1. ์ด๋ฏธ์ง€ ํŒŒ์ผ ๊ฒฝ๋กœ๋ฅผ ๋ช…๋ น์ค„์—์„œ ์ž…๋ ฅ์œผ๋กœ ๋ฐ›๋Š” ๊ฒƒ์€ ์–ด๋–ป๊ฒŒ ํ•˜์ง€?
  • sys.argv๋ฅผ ์‚ฌ์šฉ
  1. ๊ฒ€์ƒ‰ ๋Œ€์ƒ ์ด๋ฏธ์ง€๋Š” ์–ด๋””์„œ ๊ฐ€์ ธ์˜ค์ง€?
  • CIFAR-100 ์ด๋ฏธ์ง€ ์‚ฌ์šฉ

์ž‘๋™ ์ˆœ์„œ ์ •๋ฆฌ

  1. ํ”„๋กœ๊ทธ๋žจ์ด ์‹คํ–‰๋œ๋‹ค.
  2. ์ž…๋ ฅ๋œ ๊ฒฝ๋กœ์˜ ์ด๋ฏธ์ง€ ํŒŒ์ผ์„ ๋ถˆ๋Ÿฌ์˜จ๋‹ค.
  3. ๊ฒ€์ƒ‰ ๋Œ€์ƒ ์ด๋ฏธ์ง€๋“ค ์ค‘ ๋ถˆ๋Ÿฌ์˜จ ์ด๋ฏธ์ง€์™€ ๊ฐ€์žฅ ๋น„์Šทํ•œ ์ด๋ฏธ์ง€ 5๊ฐœ๋ฅผ ํ‘œ์‹œํ•œ๋‹ค.
  4. ํ”„๋กœ๊ทธ๋žจ์ด ์ข…๋ฃŒ๋œ๋‹ค.

์•„์ด๋””์–ด ๊ตฌ์ฒดํ™”

  1. ํ”„๋กœ๊ทธ๋žจ์ด ์‹คํ–‰๋œ๋‹ค.
  2. ์ž…๋ ฅ๋œ ๊ฒฝ๋กœ์˜ ์ด๋ฏธ์ง€ ํŒŒ์ผ์„ ๋ถˆ๋Ÿฌ์˜จ๋‹ค.
  3. ๊ฒ€์ƒ‰ ๋Œ€์ƒ ์ด๋ฏธ์ง€๋“ค ์ค‘ ๋ถˆ๋Ÿฌ์˜จ ์ด๋ฏธ์ง€์™€ ๊ฐ€์žฅ ๋น„์Šทํ•œ ์ด๋ฏธ์ง€ 5๊ฐœ๋ฅผ ๊ณ ๋ฅธ๋‹ค.
    1. ๊ณ ๋ฅธ ์ด๋ฏธ์ง€๋“ค์„ ํ‘œ์‹œํ•œ๋‹ค.
  1. ํ”„๋กœ๊ทธ๋žจ์ด ์ข…๋ฃŒ๋œ๋‹ค.

์—์„œ ์ข€ ๋” ๊ตฌ์ฒดํ™”

  1. ํ”„๋กœ๊ทธ๋žจ์ด ์‹คํ–‰๋œ๋‹ค.
  2. ์ž…๋ ฅ๋œ ๊ฒฝ๋กœ์˜ ์ด๋ฏธ์ง€ ํŒŒ์ผ์„ ๋ถˆ๋Ÿฌ์˜จ๋‹ค.
  3. ๊ฒ€์ƒ‰ ๋Œ€์ƒ ์ด๋ฏธ์ง€๋“ค ์ค‘ ๋ถˆ๋Ÿฌ์˜จ ์ด๋ฏธ์ง€์™€ ๊ฐ€์žฅ ๋น„์Šทํ•œ ์ด๋ฏธ์ง€ 5๊ฐœ๋ฅผ ๊ณ ๋ฅธ๋‹ค.
    3-1. ๊ฒ€์ƒ‰ ๋Œ€์ƒ ์ด๋ฏธ์ง€๋“ค์„ ๋ถˆ๋Ÿฌ์˜จ๋‹ค.
    3-2. ์ž…๋ ฅ ์ด๋ฏธ์ง€์™€ ๋น„๊ตํ•˜์—ฌ ์œ ์‚ฌ๋„๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์ˆœ์„œ๋ฅผ ๋งค๊ธด๋‹ค.
    3-3. ์œ ์‚ฌ๋„ ์ˆœ์„œ์ƒ์œผ๋กœ ์ƒ์œ„ 5๊ฐœ ์ด๋ฏธ์ง€๋ฅผ ๊ณ ๋ฅธ๋‹ค.
  4. ๊ณ ๋ฅธ ์ด๋ฏธ์ง€๋“ค์„ ํ‘œ์‹œํ•œ๋‹ค.
  5. ํ”„๋กœ๊ทธ๋žจ์ด ์ข…๋ฃŒ๋œ๋‹ค.

ํ•ต์‹ฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜ - ์œ ์‚ฌ๋„ ๊ณ„์‚ฐ ๋ฐฉ๋ฒ•

  1. ํ”„๋กœ๊ทธ๋žจ์ด ์‹คํ–‰๋œ๋‹ค.
  2. ์ž…๋ ฅ๋œ ๊ฒฝ๋กœ์˜ ์ด๋ฏธ์ง€ ํŒŒ์ผ์„ ๋ถˆ๋Ÿฌ์˜จ๋‹ค.
  3. ๊ฒ€์ƒ‰ ๋Œ€์ƒ ์ด๋ฏธ์ง€๋“ค ์ค‘ ๋ถˆ๋Ÿฌ์˜จ ์ด๋ฏธ์ง€์™€ ๊ฐ€์žฅ ๋น„์Šทํ•œ ์ด๋ฏธ์ง€ 5๊ฐœ๋ฅผ ๊ณ ๋ฅธ๋‹ค.
    3-1. ๊ฒ€์ƒ‰ ๋Œ€์ƒ ์ด๋ฏธ์ง€๋“ค์„ ๋ถˆ๋Ÿฌ์˜จ๋‹ค.
    3-2. ์ž…๋ ฅ ์ด๋ฏธ์ง€์™€ ๋น„๊ตํ•˜์—ฌ ์œ ์‚ฌ๋„๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์ˆœ์„œ๋ฅผ ๋งค๊ธด๋‹ค.
    3-2-1. ์ž…๋ ฅ ์ด๋ฏธ์ง€์™€ ๊ฒ€์ƒ‰ ๋Œ€์ƒ ์ด๋ฏธ์ง€๋“ค ์‚ฌ์ด์˜ ์œ ์‚ฌ๋„๋ฅผ ๊ณ„์‚ฐํ•œ๋‹ค.
    3-2-2. ๊ณ„์‚ฐ๋œ ์œ ์‚ฌ๋„๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์ •๋ ฌํ•˜์—ฌ ์ˆœ์„œ๋ฅผ ๋งค๊ธด๋‹ค.
    3-2. ์œ ์‚ฌ๋„ ์ˆœ์„œ์ƒ์œผ๋กœ ์ƒ์œ„ 5๊ฐœ ์ด๋ฏธ์ง€๋ฅผ ๊ณ ๋ฅธ๋‹ค.
  4. ๊ณ ๋ฅธ ์ด๋ฏธ์ง€๋“ค์„ ํ‘œ์‹œํ•œ๋‹ค.
  5. ํ”„๋กœ๊ทธ๋žจ์ด ์ข…๋ฃŒ๋œ๋‹ค.

์œ ์‚ฌ๋„๋ฅผ ํžˆ์Šคํ† ๊ทธ๋žจ๋ผ๋ฆฌ ๋น„๊ต
-> OpenCV์˜ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉ

    1. ํ”„๋กœ๊ทธ๋žจ์ด ์‹คํ–‰๋œ๋‹ค.
    1. ์ž…๋ ฅ๋œ ๊ฒฝ๋กœ์˜ ์ด๋ฏธ์ง€ ํŒŒ์ผ์„ ๋ถˆ๋Ÿฌ์˜จ๋‹ค.
    1. ๊ฒ€์ƒ‰ ๋Œ€์ƒ ์ด๋ฏธ์ง€๋“ค ์ค‘ ๋ถˆ๋Ÿฌ์˜จ ์ด๋ฏธ์ง€์™€ ๊ฐ€์žฅ ๋น„์Šทํ•œ ์ด๋ฏธ์ง€ 5๊ฐœ๋ฅผ ๊ณ ๋ฅธ๋‹ค.
      - 3-1. ๊ฒ€์ƒ‰ ๋Œ€์ƒ ์ด๋ฏธ์ง€๋“ค์„ ๋ถˆ๋Ÿฌ์˜จ๋‹ค.
      - 3-2. ์ž…๋ ฅ ์ด๋ฏธ์ง€์™€ ๋น„๊ตํ•˜์—ฌ ์œ ์‚ฌ๋„๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์ˆœ์„œ๋ฅผ ๋งค๊ธด๋‹ค.
      - 3-2-1. ์ž…๋ ฅ ์ด๋ฏธ์ง€์™€ ๊ฒ€์ƒ‰ ๋Œ€์ƒ ์ด๋ฏธ์ง€๋“ค ์‚ฌ์ด์˜ ์œ ์‚ฌ๋„๋ฅผ ๊ณ„์‚ฐํ•œ๋‹ค.
      - 3-2-1-1. ์ž…๋ ฅ ์ด๋ฏธ์ง€์™€ ๊ฒ€์ƒ‰ ๋Œ€์ƒ ์ด๋ฏธ์ง€๋“ค์„ ํ•˜๋‚˜ํ•˜๋‚˜ ํžˆ์Šคํ† ๊ทธ๋žจ์œผ๋กœ ๋งŒ๋“ ๋‹ค.
      - 3-2-1-2. OpenCV์˜ compareHist() ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ž…๋ ฅ ์ด๋ฏธ์ง€์™€ ๊ฒ€์ƒ‰ ๋Œ€์ƒ ์ด๋ฏธ์ง€ ํ•˜๋‚˜ํ•˜๋‚˜์˜ ํžˆ์Šคํ† ๊ทธ๋žจ ๊ฐ„ ์œ ์‚ฌ๋„๋ฅผ ๊ณ„์‚ฐํ•œ๋‹ค.
      - 3-2-1-3. ๊ณ„์‚ฐ๋œ ์œ ์‚ฌ๋„๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์ •๋ ฌํ•˜์—ฌ ์ˆœ์„œ๋ฅผ ๋งค๊ธด๋‹ค.
  • 3-2-2. ์œ ์‚ฌ๋„ ์ˆœ์„œ์ƒ์œผ๋กœ ์ƒ์œ„ 5๊ฐœ ์ด๋ฏธ์ง€๋ฅผ ๊ณ ๋ฅธ๋‹ค.
    1. ๊ณ ๋ฅธ ์ด๋ฏธ์ง€๋“ค์„ ํ‘œ์‹œํ•œ๋‹ค.
    1. ํ”„๋กœ๊ทธ๋žจ์ด ์ข…๋ฃŒ๋œ๋‹ค.

๊ธฐ๋Šฅ์˜ ๋ชจ๋“ˆํ™”

  • ํ”„๋กœ๊ทธ๋žจ์ด ์‹คํ–‰๋œ๋‹ค.
  • ์ž…๋ ฅ๋œ ๊ฒฝ๋กœ์˜ ์ด๋ฏธ์ง€ ํŒŒ์ผ์„ ๋ถˆ๋Ÿฌ์˜จ๋‹ค.
  • ๊ฒ€์ƒ‰ ๋Œ€์ƒ ์ด๋ฏธ์ง€๋“ค์„ ๋ถˆ๋Ÿฌ์˜จ๋‹ค.
  • ์ž…๋ ฅ ์ด๋ฏธ์ง€๋ฅผ ํžˆ์Šคํ† ๊ทธ๋žจ์œผ๋กœ ๋งŒ๋“ ๋‹ค.
  • ๊ฒ€์ƒ‰ ๋Œ€์ƒ ์ด๋ฏธ์ง€๋“ค์„ ํ•˜๋‚˜ํ•˜๋‚˜ ํžˆ์Šคํ† ๊ทธ๋žจ์œผ๋กœ ๋งŒ๋“ ๋‹ค.
  • OpenCV์˜ compareHist() ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ž…๋ ฅ ์ด๋ฏธ์ง€์™€ ๊ฒ€์ƒ‰ ๋Œ€์ƒ ์ด๋ฏธ์ง€ ํ•˜๋‚˜ํ•˜๋‚˜์˜ ํžˆ์Šคํ† ๊ทธ๋žจ ๊ฐ„ ์œ ์‚ฌ๋„๋ฅผ ๊ณ„์‚ฐํ•œ๋‹ค.
  • ๊ณ„์‚ฐ๋œ ์œ ์‚ฌ๋„๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์ •๋ ฌํ•˜์—ฌ ์ˆœ์„œ๋ฅผ ๋งค๊ธด๋‹ค.
  • ์œ ์‚ฌ๋„ ์ˆœ์„œ์ƒ์œผ๋กœ ์ƒ์œ„ 5๊ฐœ ์ด๋ฏธ์ง€๋ฅผ ๊ณ ๋ฅธ๋‹ค.
  • ๊ณ ๋ฅธ ์ด๋ฏธ์ง€๋“ค์„ ํ‘œ์‹œํ•œ๋‹ค.
  • ํ”„๋กœ๊ทธ๋žจ์ด ์ข…๋ฃŒ๋œ๋‹ค.

์ด๊ฒƒ์„ ๊ฐ€์ง€๊ณ  ๋‹ค์‹œ ์ฝ”๋“œ์Šค๋Ÿฝ๊ฒŒ.

  • ํ”„๋กœ๊ทธ๋žจ์ด ์‹คํ–‰๋œ๋‹ค.
  • ์ž…๋ ฅ๋œ ๊ฒฝ๋กœ์˜ ์ด๋ฏธ์ง€ ํŒŒ์ผ์„ ๋ถˆ๋Ÿฌ์˜จ๋‹ค.
  • ์ž…๋ ฅ ์ด๋ฏธ์ง€๋ฅผ ํžˆ์Šคํ† ๊ทธ๋žจ์œผ๋กœ ๋งŒ๋“ ๋‹ค.
  • build_histogram_db()
    - ๊ฒ€์ƒ‰ ๋Œ€์ƒ ์ด๋ฏธ์ง€๋“ค์„ ๋ถˆ๋Ÿฌ์˜จ๋‹ค.
    - ๊ฒ€์ƒ‰ ๋Œ€์ƒ ์ด๋ฏธ์ง€๋“ค์„ ํ•˜๋‚˜ํ•˜๋‚˜ ํžˆ์Šคํ† ๊ทธ๋žจ์œผ๋กœ ๋งŒ๋“ ๋‹ค.
  • search()
    - OpenCV์˜ compareHist() ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ž…๋ ฅ ์ด๋ฏธ์ง€์™€ ๊ฒ€์ƒ‰ ๋Œ€์ƒ ์ด๋ฏธ์ง€ ํ•˜๋‚˜ํ•˜๋‚˜์˜ ํžˆ์Šคํ† ๊ทธ๋žจ ๊ฐ„ ์œ ์‚ฌ๋„๋ฅผ ๊ณ„์‚ฐํ•œ๋‹ค.
    - ๊ณ„์‚ฐ๋œ ์œ ์‚ฌ๋„๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์ •๋ ฌํ•˜์—ฌ ์ˆœ์„œ๋ฅผ ๋งค๊ธด๋‹ค.
    - ์œ ์‚ฌ๋„ ์ˆœ์„œ์ƒ์œผ๋กœ ์ƒ์œ„ 5๊ฐœ ์ด๋ฏธ์ง€๋ฅผ ๊ณ ๋ฅธ๋‹ค.
  • ๊ณ ๋ฅธ ์ด๋ฏธ์ง€๋“ค์„ ํ‘œ์‹œํ•œ๋‹ค.
  • ํ”„๋กœ๊ทธ๋žจ์ด ์ข…๋ฃŒ๋œ๋‹ค.

์„ค๊ณ„๋ฅผ ์กฐ๊ธˆ๋” ๋‹จ์ˆœํ™”ํ•˜๊ธฐ ์œ„ํ•œ ๊ธฐ๋Šฅ ์ œํ•œ
-> ๊ฒ€์ƒ‰ ๋Œ€์ƒ์˜ ์ด๋ฏธ์ง€ ์ค‘ ํ•˜๋‚˜์˜ ์ด๋ฆ„์„ ์ž…๋ ฅ๋ฐ›๋Š” ๊ฒƒ.

  • ํ”„๋กœ๊ทธ๋žจ์ด ์‹คํ–‰๋œ๋‹ค.
  • ์ž…๋ ฅ๋œ ๊ฒฝ๋กœ์˜ ์ด๋ฏธ์ง€ ํŒŒ์ผ์„ ๋ถˆ๋Ÿฌ์˜จ๋‹ค.
  • build_histogram_db()
    - CIFAR-100 ์ด๋ฏธ์ง€๋“ค์„ ๋ถˆ๋Ÿฌ์˜จ๋‹ค.
    - CIFAR-100 ์ด๋ฏธ์ง€๋“ค์„ ํ•˜๋‚˜ํ•˜๋‚˜ ํžˆ์Šคํ† ๊ทธ๋žจ์œผ๋กœ ๋งŒ๋“ ๋‹ค.
    - CIFAR-100 ํžˆ์Šคํ† ๊ทธ๋žจ ์ค‘ ์ž…๋ ฅ๋œ ์ด๋ฏธ์ง€ ์ด๋ฆ„์— ํ•ด๋‹นํ•˜๋Š” ํžˆ์Šคํ† ๊ทธ๋žจ์„ ์ž…๋ ฅ ์ด๋ฏธ์ง€๋กœ ์„ ํƒํ•œ๋‹ค.
  • search()
    - OpenCV์˜ compareHist() ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ž…๋ ฅ ์ด๋ฏธ์ง€์™€ ๊ฒ€์ƒ‰ ๋Œ€์ƒ ์ด๋ฏธ์ง€ ํ•˜๋‚˜ํ•˜๋‚˜์˜ ํžˆ์Šคํ† ๊ทธ๋žจ ๊ฐ„ ์œ ์‚ฌ๋„๋ฅผ ๊ณ„์‚ฐํ•œ๋‹ค.
    - ๊ณ„์‚ฐ๋œ ์œ ์‚ฌ๋„๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์ •๋ ฌํ•˜์—ฌ ์ˆœ์„œ๋ฅผ ๋งค๊ธด๋‹ค.
    - ์œ ์‚ฌ๋„ ์ˆœ์„œ์ƒ์œผ๋กœ ์ƒ์œ„ 5๊ฐœ ์ด๋ฏธ์ง€๋ฅผ ๊ณ ๋ฅธ๋‹ค.
  • ๊ณ ๋ฅธ ์ด๋ฏธ์ง€๋“ค์„ ํ‘œ์‹œํ•œ๋‹ค.
  • ํ”„๋กœ๊ทธ๋žจ์ด ์ข…๋ฃŒ๋œ๋‹ค.

์„ค๊ณ„ ๊ณผ์ • ์™„์„ฑ

  • ๊ฐ ํ•จ์ˆ˜์— ์ž…๋ ฅ๋˜๊ณ  ๋ฐ˜ํ™˜๋  ๋ฐ์ดํ„ฐ์˜ ํ˜•ํƒœ์™€ ๋ณ€์ˆ˜๋ช… ์ •ํ•˜๊ธฐ
  • ํ”„๋กœ๊ทธ๋žจ์ด ์‹คํ–‰๋œ๋‹ค.

  • build_histogram_db()
    - CIFAR-100 ์ด๋ฏธ์ง€๋“ค์„ ๋ถˆ๋Ÿฌ์˜จ๋‹ค.
    - CIFAR-100 ์ด๋ฏธ์ง€๋“ค์„ ํ•˜๋‚˜ํ•˜๋‚˜ ํžˆ์Šคํ† ๊ทธ๋žจ์œผ๋กœ ๋งŒ๋“ ๋‹ค.
    - ์ด๋ฏธ์ง€ ์ด๋ฆ„์„ ํ‚ค๋กœ ํ•˜๊ณ , ํžˆ์Šคํ† ๊ทธ๋žจ์„ ๊ฐ’์œผ๋กœ ํ•˜๋Š” ๋”•์…”๋„ˆ๋ฆฌ histogram_db๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

  • CIFAR-100 ํžˆ์Šคํ† ๊ทธ๋žจ ์ค‘ ์ž…๋ ฅ๋œ ์ด๋ฏธ์ง€ ์ด๋ฆ„์— ํ•ด๋‹นํ•˜๋Š” ํžˆ์Šคํ† ๊ทธ๋žจ์„ ์ž…๋ ฅ ์ด๋ฏธ์ง€๋กœ ์„ ํƒํ•˜์—ฌ target_histogram์ด๋ผ๋Š” ๋ณ€์ˆ˜๋ช…์œผ๋กœ ์ง€์ •ํ•œ๋‹ค.

  • search()
    - ์ž…๋ ฅ ์ด๋ฏธ์ง€ ํžˆ์Šคํ† ๊ทธ๋žจ target_histogram์™€ ์ „์ฒด ๊ฒ€์ƒ‰ ๋Œ€์ƒ ์ด๋ฏธ์ง€๋“ค์˜ ํžˆ์Šคํ† ๊ทธ๋žจ์„ ๊ฐ€์ง„ ๋”•์…”๋„ˆ๋ฆฌ histogram_db๋ฅผ ์ž…๋ ฅ์œผ๋กœ ๋ฐ›๋Š”๋‹ค.
    - OpenCV์˜ compareHist() ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ž…๋ ฅ ์ด๋ฏธ์ง€์™€ ๊ฒ€์ƒ‰ ๋Œ€์ƒ ์ด๋ฏธ์ง€ ํ•˜๋‚˜ํ•˜๋‚˜์˜ ํžˆ์Šคํ† ๊ทธ๋žจ ๊ฐ„ ์œ ์‚ฌ๋„๋ฅผ ๊ณ„์‚ฐํ•œ๋‹ค. ๊ฒฐ๊ณผ๋Š” result๋ผ๋Š” ์ด๋ฆ„์˜ ๋”•์…”๋„ˆ๋ฆฌ๋กœ, ํ‚ค๋Š” ์ด๋ฏธ์ง€ ์ด๋ฆ„, ๊ฐ’์€ ์œ ์‚ฌ๋„๋กœ ํ•œ๋‹ค.
    - ๊ณ„์‚ฐ๋œ ์œ ์‚ฌ๋„๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์ •๋ ฌํ•˜์—ฌ ์ˆœ์„œ๋ฅผ ๋งค๊ธด๋‹ค.
    - ์œ ์‚ฌ๋„ ์ˆœ์„œ์ƒ์œผ๋กœ ์ƒ์œ„ 5๊ฐœ ์ด๋ฏธ์ง€๋งŒ ๊ณจ๋ผ์„œ result์— ๋‚จ๊ธด๋‹ค.

  • ๊ณ ๋ฅธ ์ด๋ฏธ์ง€๋“ค์„ ํ‘œ์‹œํ•œ๋‹ค.

  • ํ”„๋กœ๊ทธ๋žจ์ด ์ข…๋ฃŒ๋œ๋‹ค.

์ฝ”๋“œ๋กœ ๊ตฌํ˜„

์ข‹์€ ์›นํŽ˜์ด์ง€ ์ฆ๊ฒจ์ฐพ๊ธฐ