차이 연산
그레이스케일(grayscale)의 범위는 0~255이다. 0은 가장 어두운 검은색이고 255는 가장 밝은 흰색이다. 따라서 같은 이미지라면 그레이스케일의 차가 0이 된다. 다른 부분이 있다면, 두 이미지의 그레이스케일의 차의 절댓값으로 새 이미지를 생성(차이 연산)하면 확연히 다른 부분만 두드러져 보이게 될 것이다. 이러한 특성을 이용해서 두 이미지의 사이의 변화점을 검출할 수 있다.
관련 이론은 Visual C++ 영상 처리 프로그래밍에 잘 설명되어 있으니 참고하면 된다.
파이썬으로 차이 연산을 구현해 보았다.
서로 다른 특정 부분이 있는 이미지를 준비한다. 첫 번째 이미지에는 없고 두 번째 이미지에는 사람이 등장한다. (이미지는 하단 참조 링크에서 다운) 해당 이미지를 차이 연산을 통해서 새 이미지를 생성하면 다음과 같이 사람 부분이 확연히 눈에 띈다. 변화점이 분명히 감지된다.
이번에는 약간 파이썬 변수와 함수명 규칙을 지켜보려고 시도해 봤다.
import matplotlib.pyplot as plt
import cv2
def draw_image(original_img, different_img, result_img, title, sub_title1, sub_title2, sub_title3):
fig = plt.figure()
fig.suptitle(title)
ax = fig.add_subplot(1, 3, 1)
ax.imshow(original_img, cmap=plt.cm.gray)
ax.set_title(sub_title1)
ax = fig.add_subplot(1, 3, 2)
ax.imshow(different_img, cmap=plt.cm.gray)
ax.set_title(sub_title2)
ax = fig.add_subplot(1, 3, 3)
ax.imshow(result_img, cmap=plt.cm.gray)
ax.set_title(sub_title3)
plt.show()
def do_sub_operation():
file1_path = "img\\diff1.bmp"
file2_path = "img\\diff2.bmp"
img1 = cv2.imread(file1_path, cv2.IMREAD_GRAYSCALE)
img2 = cv2.imread(file2_path, cv2.IMREAD_GRAYSCALE)
out_img = img1.copy()
row, col = img1.shape
for i in range(0, row):
for j in range(0, col):
if img1[i, j] >= img2[i, j]:
diff = img1[i, j] - img2[i, j]
else:
diff = img2[i, j] - img1[i, j]
# print("diff = ", diff)
out_img[i, j] = diff
draw_image(img1, img2, out_img, "Subtraction Operation", "Original Image", "Different Image", "Result")
cv2.imwrite("sub_operation.bmp", out_img)
do_sub_operation()
ref.)
Visual C++ 영상 처리 프로그래밍 : https://thebook.io/006796/ch07/01/04_01/
이미지 출처 : https://github.com/gilbutITbook/006796/tree/master/images/ch07