신규 블로그를 만들었습니다!
OpenCV 설치
pip 최신버전으로 업데이트를 진행합니다.
python -m pip install --upgrade pip
pip를 이용한 필요한 패키지 설치를 합니다.
pip install matplotlib
pip install numpy
pip install OpenCV-Python
설치 확인
설치가 완료되었으면, python에서 import cv2를 통해 제대로 import가 이루어지는지 확인합니다. 만약 import를 할 수 없다는 에러(Error)가 발생하면 제대로 설치되지 않았다는 뜻이므로, 처음부터 절차대로 다시 진행하시길 바랍니다.
OpenCV를 이용한 Feature Matching
위에서 설치를 하셨다면, 이제 Feature Matching을 진행합니다. 코드는 비교적 간단합니다. 요약하면 순서는 2단계로 나눠집니다. 내용은 아래와 같습니다.
2개의 이미지 객체 생성 > 만들어진 이미지 객체들을 서로 비교
1. 이미지 객체 가져오기
보통 이미지 객체를 생성할 때, 색상을 제거하고 흑백으로 생성을 합니다. 이 부분에 대해서는 자세히는 모르겠지만, 이미지를 서로 비교하기 좋게 만드는 과정 중 하나입니다.
import cv2
import numpy as np
from matplotlib import pyplot as plt
class compareImg :
def __init__(self) :
pass
def readImg(self, filepath) :
img = cv2.imread(filepath, cv2.IMREAD_GRAYSCALE)
cv2.namedWindow("root", cv2.WINDOW_NORMAL) # window 생성
cv2.imshow("root", img) # window에 이미지 띄우기
cv2.waitKey(5000) # 5초 기다림. 아무키나 입력되면 대기 종료
cv2.destroyAllWindows() # window 제거
return img
def run(self) :
# 이미지 파일 경로 설정
filepath1 = r"C:\dev\python\workspace\img\simson1.png"
filepath2 = r"C:\dev\python\workspace\img\simson2.png"
# 이미지 객체 가져옴
img1 = self.readImg(filepath1)
img2 = self.readImg(filepath2)
if __name__ == '__main__':
cImg = compareImg()
cImg.run()
일단, 이미지 객체를 잘 불러오는지 확인을 해봅니다.
10번째 줄 : 이미지 객체 생성
11번째 줄 ~ 14번째 줄 : 윈도우 창 생성 및 이미지 출력
15번째 줄 : 추후에 이미지 객체를 사용해야 하므로, 이미지 객체를 return값으로 설정
실행 결과
심슨 사진을 가지고 진행했습니다. 정상적으로 이미지를 가져옵니다.
위 과정은 확인 차원에서 해본 것이고, 본격적으로 두개의 이미지를 비교합니다.
2. 이미지 비교(피처 매칭)
가져온 2개의 이미지를 서로 비교합니다.
import cv2
import numpy as np
from matplotlib import pyplot as plt
class compareImg :
def __init__(self) :
pass
def readImg(self, filepath) :
img = cv2.imread(filepath, cv2.IMREAD_GRAYSCALE)
# cv2.namedWindow("root", cv2.WINDOW_NORMAL) # window 생성
# cv2.imshow("root", img) # window에 이미지 띄우기
# cv2.waitKey(5000) # 5초 기다림. 아무키나 입력되면 대기 종료
# cv2.destroyAllWindows() # window 제거
return img
def diffImg(self, img1, img2) :
# Initiate SIFT detector
orb = cv2.ORB_create()
# find the keypoints and descriptors with SIFT
kp1, des1 = orb.detectAndCompute(img1, None)
kp2, des2 = orb.detectAndCompute(img2, None)
# create BFMatcher object
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
# Match descriptors.
matches = bf.match(des1,des2)
# Sort them in the order of their distance.
matches = sorted(matches, key = lambda x:x.distance)
# BFMatcher with default params
bf = cv2.BFMatcher()
matches = bf.knnMatch(des1, des2, k=2)
# Apply ratio test
good = []
for m,n in matches:
if m.distance < 0.75 * n.distance:
good.append([m])
# Draw first 10 matches.
knn_image = cv2.drawMatchesKnn(img1, kp1, img2, kp2, good, None, flags=2)
plt.imshow(knn_image)
plt.show()
def run(self) :
# 이미지 파일 경로 설정
filepath1 = r"C:\dev\python\workspace\img\simson1.png"
filepath2 = r"C:\dev\python\workspace\img\simson2.png"
# 이미지 객체 가져옴
img1 = self.readImg(filepath1)
img2 = self.readImg(filepath2)
# 2개의 이미지 비교
self.diffImg(img1, img2)
if __name__ == '__main__':
cImg = compareImg()
cImg.run()
20번째 줄 ~ 24번째 줄 : keypoint와 descriptor를 가져옵니다.
27번째 줄 ~ 37번째 줄 : Match를 통해 이미지를 비교합니다.
40번째 줄 ~ 43번째 줄 : ratio를 설정해서 좀 더 정확한 값을 얻을 수 있습니다. ratio에 따라 결과가 어떻게 달라지는지 아래에서 소개하겠습니다. 비교해서 유사한 점을 얻어 "good"이라는 임의의 리스트에 넣습니다.
47번째 줄 ~ 48번째 줄 : 비교한 이미지를 윈도우 창에 띄어줍니다.
실행결과
Ratio에 따른 결과
Ratio 1부터 0까지 조금씩 줄여보면서, 차이를 살펴보겠습니다. Ratio의 값을 줄일수록 이미지 유사도 거리가 줄어들어 조금 더 정확한 값을 보입니다. 하지만 너무 줄이면, 원하는 결과를 얻기 힘듭니다.
상황에 따라 적당한 ratio값을 설정해주는 것이 중요해 보입니다.
Ratio : 1
전혀 알 수 없는 결과가 나옵니다.
Ratio : 0.8
0.8로 유사도 거리를 줄여본 결과, 어느 부분이 비슷한지 얼추 나옵니다.
Ratio : 0.75
점점 줄여보면 조금 더 정확한 값이 나옵니다.
Ratio : 0.6
대략 0.6일때 정확한 값들이 나오는군요.
Ratio : 0.4
Ratio : 0.3
Ratio : 0.2
Ratio : 0
일치하는 부분이 없다고 나옵니다.
느낀점
사실 거의 동일한 사진이어서 유사한 부분이 많이 나올줄 알았지만, 생각보다 그러진 않았습니다.
아직 OpenCV를 많이 사용해보지도 않았고, 이미지 비교하는 것에 대한 공부를 이제 막 시작하여 부족한 부분이 많습니다.
위 내용은 간단한 기능만을 이용해 만들었습니다. 코딩해보고 결과를 통해 느낀바로는... 이미지 비교하는데 Feature Matching을 이용하는 것이 그렇게 효율적이지는 않아보인다는 것입니다.
좀 더 공부를 통해 효율적인 이미지 비교하는 방법을 포스팅 하도록 하겠습니다.
다른 글
2018/05/25 - [IoT] - 정적인 사진에서 OpenCV를 이용한 얼굴인식(Python 파이썬 코드)
'Language > Python' 카테고리의 다른 글
pyinstaller를 이용한 Python exe 실행 파일 만들기 (86) | 2019.01.13 |
---|---|
파이썬의 @property 개념 및 사용방법(접근지정자와 GET, SET 메소드) (0) | 2018.12.27 |
Python :: 파이썬3 디렉토리 및 파일 삭제, os 모듈과 shutil 모듈 사용하기 (0) | 2018.10.26 |
Python :: 파이썬에서 private과 public 변수 사용하기(파이썬의 범위 scope) (0) | 2018.10.21 |
Python :: 파이썬 집합 자료형 Set, 중복제거할때나 집합형태에 편리한 Set (0) | 2018.10.19 |
최근댓글