brunch

You can make anything
by writing

C.S.Lewis

by 서준수 May 14. 2019

파이썬 이미지 프로세싱 (1)

평균 연산

파이썬 이미지 프로세싱 (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.)

Visual C++ 영상 처리 프로그래밍 : https://thebook.io/006796/ch07/01/03_01/

이미지 출처 : https://github.com/gilbutITbook/006796/blob/master/images/ch07/

matplotlib 설치 : https://mainia.tistory.com/5617

OpenCV 이미지 읽기 : https://zzsza.github.io/data/2018/01/23/opencv-1/

그레이스케일 출력 : https://datascienceschool.net/view-notebook/9af8d8e93c084bc49f0ac2bb8a20e2a4/

픽셀 읽기 : https://m.blog.naver.com/PostView.nhn?blogId=samsjang&logNo=220502203203&proxyReferer=https%3A%2F%2Fwww.google.co.kr%2F

그래프 출력 : https://wikidocs.net/4761

함수 사용법 : https://www.codingfactory.net/10034

매거진의 이전글 파이썬 이미지 프로세싱 (2)
브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari