파이썬 이미지 프로세싱 (1)
파이썬은 처음 써본다. 그래서 기본적인 문법도 잘 모른다. (심지어 함수 호출하는 법도 검색했다.)
그런데 이미지 프로세싱을 한다고? 가능했다.
그만큼 파이썬이 자료도 많고 접근성도 쉬운 언어인 것 같다.
그래서 무엇을 할 것인가?
노이즈가 있는 이미지 8장을 이용하여 평균 연산을 통해서 노이즈를 제거해 볼 것이다.
관련 설명과 방법은 'Visual C++ 영상 처리 프로그래밍 (황성규 저)'에 있는 내용을 참고하였다. (아주 잘 설명되어 있으니 꼭 보길 추천) 해당 도서에 C++로 짜인 코드가 있는데 사실 알고리즘 자체는 단순하다. 각 픽셀의 그레이스케일의 평균값을 구해서 해당 값으로 이루어진 새로운 이미지를 만들어 내는 것이다.
간단한 예를 들어보겠다. 다음과 같은 그레이스케일 값을 가지는 3x3 해상도의 이미지가 2개 있다고 가정해보자. 255 값은 노이즈이다. 즉 좌항의 좌측 이미지와 우측 이미지에 각각 1개씩 노이즈가 있는 것이다. 참고로 그레이스케일 값이 작을수록 어두운 것이다.
이때 노이즈를 제거하기 위해서 두 이미지의 그레이스케일 값 평균을 구한다. 해당 값으로 새로운 이미지를 만들면 기존보다 현저히 노이즈가 줄어드는 것을 알 수 있다.
평균 연산의 원리
간단한 원리지만 결과물은 꽤 훌륭하다.
C++ 코드를 참고하여 파이썬으로 다시 작성한 결과는 다음과 같다.
평균 연산으로 노이즈가 제거된 모습
파이썬은 잘 모르지만 이 코드가 좋은 코드가 아니라는 것은 알 수 있다. 변수명도 대문자를 쓰지 말라고 경고가 뜨기도 하고 배열도 쓰지 않았고, 그냥 참고용이다. ^^;
import matplotlib.pyplot as plt
import cv2
def drawImage(img1, img2, title, subTitle1, subTitle2):
fig = plt.figure()
fig.suptitle(title)
ax1 = fig.add_subplot(1, 2, 1)
ax1.imshow(img1, cmap=plt.cm.gray)
ax1.set_title(subTitle1)
ax2 = fig.add_subplot(1, 2, 2)
ax2.imshow(img2, cmap=plt.cm.gray)
ax2.set_title(subTitle2)
plt.show()
def doAveOp():
file1_path = "img\\noise1.bmp"
file2_path = "img\\noise2.bmp"
file3_path = "img\\noise3.bmp"
file4_path = "img\\noise4.bmp"
file5_path = "img\\noise5.bmp"
file6_path = "img\\noise6.bmp"
file7_path = "img\\noise7.bmp"
file8_path = "img\\noise8.bmp"
img1 = cv2.imread(file1_path, cv2.IMREAD_GRAYSCALE)
img2 = cv2.imread(file2_path, cv2.IMREAD_GRAYSCALE)
img3 = cv2.imread(file3_path, cv2.IMREAD_GRAYSCALE)
img4 = cv2.imread(file4_path, cv2.IMREAD_GRAYSCALE)
img5 = cv2.imread(file5_path, cv2.IMREAD_GRAYSCALE)
img6 = cv2.imread(file6_path, cv2.IMREAD_GRAYSCALE)
img7 = cv2.imread(file7_path, cv2.IMREAD_GRAYSCALE)
img8 = cv2.imread(file8_path, cv2.IMREAD_GRAYSCALE)
out_img = img1.copy()
row, col = img1.shape
for i in range(0, row):
for j in range(0, col):
inputList = [img1[i, j], img2[i, j], img3[i, j], img4[i, j], img5[i, j], img6[i, j], img7[i, j], img8[i, j]]
diff = sum(inputList) / len(inputList)
# print("diff = ", diff)
out_img[i, j] = diff
drawImage(img1, out_img, "Average Operation", "Original Image", "Result Image")
cv2.imwrite("ave_oper.bmp", out_img)
doAveOp()
ref.)