brunch

라이킷 8 댓글 공유 작가의 글을 SNS에 공유해보세요

You can make anything
by writing

C.S.Lewis

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

평균 연산

by 서준수 May 14. 2019

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

매거진의 이전글 C언어 빌드 과정 (build process)

브런치 로그인

브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari