본문 바로가기

프로그래밍/Python

Gray Scale 영상처리 : 이미지 불러오기

코딩 구조도


전체 코딩
## GrayScale Image Processing using Python (Ver 2.2)
import math
import os.path
from tkinter import *
from tkinter import messagebox
from tkinter.filedialog import *
from tkinter.simpledialog import *

## 함수부
def malloc2D(h, w, initValue =0) :
    memory = [[initValue for _ in range(w)] for _ in range(h)]
    return memory

def  openDocument() :
    global inImage, outImage, inH, inW, outH, outW
    global window, canvas, paper
    filename = askopenfilename(parent=window,
            filetypes=(("RAW 파일", "*.raw"), ("모든파일", "*.*")))
    # 중요! 입력 영상의 크기를 파악
    fSize = os.path.getsize(filename) # 파일 크기(Byte)
    inH = inW = int(math.sqrt(fSize)) # 256x256
    # 메모리 할당
    inImage = malloc2D(inH, inW)
    rfp = open(filename, 'rb')
    for i in range(inH):
        for k in range(inW):
            inImage[i][k] = ord(rfp.read(1))
    rfp.close()
    equalImage()

def drawImage() :
    global inImage, outImage, inH, inW, outH, outW
    global window, canvas, paper
    if canvas != None :
        canvas.destroy()

    window.geometry(str(outH) + 'x' + str(outW) )
    ## 캔버스/페이퍼 생성
    canvas = Canvas(window, height=outH, width=outW)
    paper = PhotoImage(height=outH, width=outW)
    canvas.create_image((outH / 2, outW / 2), image=paper, state='normal')
    ## 메모리 --> 화면으로 찍기
    # for i in range(outH) :
    #     for k in range(outW) :
    #         r = g = b = outImage[i][k]
    #         paper.put("#%02x%02x%02x" % (r, g, b), (k, i))
    ## 더블 버퍼링 기법과 비스므레~~~~
    rgbString=""
    for i in range(outH):
        tmpString = ""
        for k in range(outW):
            r = g = b = outImage[i][k]
            tmpString += "#%02x%02x%02x " % (r, g, b) # 제일 뒤에 공백
        rgbString += '{' + tmpString + '} ' # 제일 뒤에 공백
    paper.put(rgbString)

    canvas.pack()


### 영상처리 함수 모음 ###
def equalImage() :
    global inImage, outImage, inH, inW, outH, outW
    global window, canvas, paper
    # 중요! 출력영상의 크기를 결정 --> 알고리즘에 의존
    outH = inH
    outW = inW
    # 메모리 할당
    outImage = malloc2D(outH, outW)
    ## ** 진짜 영상처리 알고리즘 ** ##
    for i in range(inH) :
        for k in range(inW) :
            outImage[i][k] = inImage[i][k]
    #################################
    drawImage()

## 전역변수부
inImage, outImage = [], []  # unsinged char ** m_inImage, ** m_outImage
inH, inW, outH, outW = [0] * 4
window, canvas, paper = None, None, None

## 메인코드부
window = Tk() # 벽
window.title("Gray영상처리 Ver2.2")
window.geometry('500x500')

mainMenu = Menu(window) # 메뉴의 틀
window.config(menu=mainMenu)

fileMenu = Menu(mainMenu) # 상위 메뉴(파일)
mainMenu.add_cascade(label='파일', menu=fileMenu)
fileMenu.add_command(label='열기', command=openDocument)
fileMenu.add_command(label='저장')
fileMenu.add_separator()
fileMenu.add_command(label='종료')

image1Menu = Menu(mainMenu) # 상위 메뉴(파일)
mainMenu.add_cascade(label='화소점처리', menu=image1Menu)
image1Menu.add_command(label='동일영상', command=equalImage)
image1Menu.add_command(label='반전영상', command=reverseImage)

window.mainloop()

라이브러리
import math
import os.path
from tkinter import *
from tkinter import messagebox
from tkinter.filedialog import *
from tkinter.simpledialog import *

- math는 복잡한 연산이 필요할 때 사용

- os.path는 파일 경로를 생성, 수정하고 파일 정보를 쉽게 다룸

- 나머지는 파이썬으로 윈도우 창을 띄우기 위해 사용


함수 부분_메모리할당
def malloc2D(h, w, initValue =0) :
    memory = [[initValue for _ in range(w)] for _ in range(h)]
    return memory

- 메모리 할당 함수

- w x h 만큼의 배열을 준비

 

함수 부분_파일 열기
def  openDocument() :
    global inImage, outImage, inH, inW, outH, outW
    global window, canvas, paper
    filename = askopenfilename(parent=window,
            filetypes=(("RAW 파일", "*.raw"), ("모든파일", "*.*")))
    # 중요! 입력 영상의 크기를 파악
    fSize = os.path.getsize(filename) # 파일 크기(Byte)
    inH = inW = int(math.sqrt(fSize)) # 256x256
    # 메모리 할당
    inImage = malloc2D(inH, inW)
    rfp = open(filename, 'rb')
    for i in range(inH):
        for k in range(inW):
            inImage[i][k] = ord(rfp.read(1))
    rfp.close()
    equalImage()

 

 

 

    filename = askopenfilename(parent=window,
            filetypes=(("RAW 파일", "*.raw"), ("모든파일", "*.*")))

1. 파일 이름과 파일 타입을 물음

 

    fSize = os.path.getsize(filename) # 파일 크기(Byte)
    inH = inW = int(math.sqrt(fSize)) # 256x256

2. filename 파일 사이즈를 파악

  - math.sqrt = 제곱근으로 변환

    : 때문에 파일 높이와 너비가 같음

 

    inImage = malloc2D(inH, inW)
    rfp = open(filename, 'rb')
    for i in range(inH):
        for k in range(inW):
            inImage[i][k] = ord(rfp.read(1))
    rfp.close()

3. 메모리 할당

 

    equalImage()

4. 이미지 출력

 

함수 부분_이미지 그리기
def drawImage() :
    global inImage, outImage, inH, inW, outH, outW
    global window, canvas, paper
    if canvas != None :
        canvas.destroy()

    window.geometry(str(outH) + 'x' + str(outW) )
    ## 캔버스/페이퍼 생성
    canvas = Canvas(window, height=outH, width=outW)
    paper = PhotoImage(height=outH, width=outW)
    canvas.create_image((outH / 2, outW / 2), image=paper, state='normal')
    ## 메모리 --> 화면으로 찍기
    # for i in range(outH) :
    #     for k in range(outW) :
    #         r = g = b = outImage[i][k]
    #         paper.put("#%02x%02x%02x" % (r, g, b), (k, i))
    ## 더블 버퍼링 기법과 비스므레~~~~
    rgbString=""
    for i in range(outH):
        tmpString = ""
        for k in range(outW):
            r = g = b = outImage[i][k]
            tmpString += "#%02x%02x%02x " % (r, g, b) # 제일 뒤에 공백
        rgbString += '{' + tmpString + '} ' # 제일 뒤에 공백
    paper.put(rgbString)

    canvas.pack()

 

    if canvas != None :
        canvas.destroy()

1. 이전 캔버스 초기화

 

    window.geometry(str(outH) + 'x' + str(outW) )
    ## 캔버스/페이퍼 생성
    canvas = Canvas(window, height=outH, width=outW)
    paper = PhotoImage(height=outH, width=outW)
    canvas.create_image((outH / 2, outW / 2), image=paper, state='normal')

2. window창, canvas, paper(이미지 다운로드 공간) 생성

  - paper 중심위치는 캔버스의 중앙

 

     for i in range(outH) :
         for k in range(outW) :
             r = g = b = outImage[i][k]
             paper.put("#%02x%02x%02x" % (r, g, b), (k, i))
     
     canvas.pack()

3-1. 메모리 할당

  - 그레이스케일이기때문에 r=g=b로 설정

※ 큰 이미지를 다운로드시 느림

    rgbString=""
    for i in range(outH):
        tmpString = ""
        for k in range(outW):
            r = g = b = outImage[i][k]
            tmpString += "#%02x%02x%02x " % (r, g, b) # 제일 뒤에 공백
        rgbString += '{' + tmpString + '} ' # 제일 뒤에 공백
    paper.put(rgbString)
    
    canvas.pack()

3-2. 메모리 할당 2

  1) rgbString 문자열을 준비

  2) for i in range(outH)가 한번 돌때마다 tmpSrting 문자열 하나 준비

  3) for k in range가 outW 만큼 반복

     1- 그레이 스케일이기 때문에 r = g = b로 설정

     2- tmpString 문자열에 (r, g, b)가 하나씩 outW번 추가

  4) rgbString에  tmpString을 한줄씩 추가 : {tmpString } 형태로

  5) 저장된 rgdString 전체가 paper에 출력

※ 다운 속도가 빨라짐

 

함수부분_동일이미지
def equalImage() :
    global inImage, outImage, inH, inW, outH, outW
    global window, canvas, paper
    # 중요! 출력영상의 크기를 결정 --> 알고리즘에 의존
    outH = inH
    outW = inW
    # 메모리 할당
    outImage = malloc2D(outH, outW)
    ## ** 진짜 영상처리 알고리즘 ** ##
    for i in range(inH) :
        for k in range(inW) :
            outImage[i][k] = inImage[i][k]
    #################################
    drawImage()

 

    outH = inH
    outW = inW
    # 메모리 할당
    outImage = malloc2D(outH, outW)

1. outH와 outW의 크기를 결정

2. outH, outW만큼의 outImage크기 결정

 

    for i in range(inH) :
        for k in range(inW) :
            outImage[i][k] = inImage[i][k]
    #################################
    drawImage()

3. inImage를 outImage에 대입

4. 이미지 출력


전역 변수
inImage, outImage = [], []  # unsinged char ** m_inImage, ** m_outImage
inH, inW, outH, outW = [0] * 4
window, canvas, paper = None, None, None

 

메인 함수
window = Tk() # 벽
window.title("Gray영상처리 Ver2.2")
window.geometry('500x500')

mainMenu = Menu(window) # 메뉴의 틀
window.config(menu=mainMenu)

fileMenu = Menu(mainMenu) # 상위 메뉴(파일)
mainMenu.add_cascade(label='파일', menu=fileMenu)
fileMenu.add_command(label='열기', command=openDocument)
fileMenu.add_command(label='저장')
fileMenu.add_separator()
fileMenu.add_command(label='종료')

image1Menu = Menu(mainMenu) # 상위 메뉴(파일)
mainMenu.add_cascade(label='화소점처리', menu=image1Menu)
image1Menu.add_command(label='동일영상', command=equalImage)
image1Menu.add_command(label='반전영상')

window.mainloop()

 

window = Tk() # 벽
window.title("Gray영상처리 Ver2.2")
window.geometry('500x500')

1. window창 생성

2. window 위쪽 바 : Gray영상처리 Ver2.2

3. window창 크기 : 500 x 500

 

mainMenu = Menu(window) # 메뉴의 틀
window.config(menu=mainMenu)

4. config는 윈도우창 바아래 부분, menu는 mainMenu로 받음

 

fileMenu = Menu(mainMenu) # 상위 메뉴(파일)
mainMenu.add_cascade(label='파일', menu=fileMenu)
fileMenu.add_command(label='열기', command=openDocument)
fileMenu.add_command(label='저장')
fileMenu.add_separator()
fileMenu.add_command(label='종료')

image1Menu = Menu(mainMenu) # 상위 메뉴(파일)
mainMenu.add_cascade(label='화소점처리', menu=image1Menu)
image1Menu.add_command(label='동일영상', command=equalImage)
image1Menu.add_command(label='반전영상')

5. 파일 메뉴 만들어 누르면 함수가 작동

 

window.mainloop()

6. window창은 루프로 동작


결과

 

'프로그래밍 > Python' 카테고리의 다른 글

Gray Scale 영상처리 : 2단 흑백영상  (0) 2022.02.20
Gray Scale 영상처리 : 반전 이미지  (0) 2022.02.18
파이썬 GUI  (0) 2022.02.17
바이너리 파일처리  (0) 2022.02.17
파일 처리  (0) 2022.02.17