본문 바로가기
대한상공회의소 스마트팩토리 교육/C# 프로그래밍

[시각화 프로그래밍] Gray Scale Image Processing Using C# «수업-1» : 디지털 이미지 파일 열기(Open) 및 표시(Display)

by 나는영하 2022. 4. 5.

※ 주의사항 

본 블로그는 수업 내용을 바탕으로 제가 이해한 부분을 정리한 블로그입니다.
본 내용을 참고로만 보시고, 틀린 부분이 있다면 지적 부탁드립니다!

감사합니다😁

 

안녕하세요!!

오늘은 아래와 같은 내용을 확인해보겠습니다.

 

디지털 이미지 처리 과정(개요)

이미지 파일 열기

이미지 파일 표시(Display)

C# Window Form (GUI)


새로운 과목이 시작되었습니다!!

지난 약 400여시간동안 PLC와 마이크로프로세서(ATmega 및 Arduino)에 대해 배워보았었습니다.

앞으로는 프로그래밍 과목인 C#에 대해 배워보도록 하겠습니다.

단순히 C# 언어의 기능과 코드만을 배우면 재미도 없고 성취감도 없기 때문에

그레이 스케일 이미지를 가공하고 처리하는 프로그램을 만드것을 목표로 C#에 대해 알아가보도록 하겠습니다!! 

1. Digital Gray Scale Image 처리 과정

디지털 영상처리 프로그램 구성도

※ 영상처리 프로그램에 사용되는 Image

- 일반 Color사진이 아닌 Gray Scale(회색조) 사진을 가공하도록 하겠습니다.

(코딩의 난이도 조절을 위해 사진의 가로, 세로 길이가 같고 무채색 계열의 사진 가공)

- 따라서, 본 프로그램에 사용되는 사진의 확장자는 "RAW" 입니다.

 

※ 영상처리 프로그램 기본 함수 처리 순서

✔ 첫째, 영상처리에 사용할 이미지를 연다

✔ 둘째, 해당 이미지의 폭과 높이를 구해서 2차원 배열의 메모리를 할당한다.(inImage[ , ])

✔ 셋째, 이미지 파일내의 값을 메모리에 옮긴다

✔ 넷재, 출력할 이미지의 크기를 결정한다.

✔ 다섯째, 열때와 동일하게 출력 이미지의 메모리를 할당한다(outImage[ , ])

✔ 여섯째, open한 이미지를 가공하기 위한 알고리즘을 작성하고, 값을 메모리에 옮긴다.

✔ 일곱번째, 출력 이미지 메모리를 display 한다.

 

- 위의 일곱개의 과정은 영상처리 공통 과정에 속하며 이중에서 여섯번째 과정은 이미지를 가공하고 처리하는 영상처리 알고리즘에 해당된다. 따라서 여섯번째의 과정은 다양한 기능과 항목으로 나뉘어서 기능이 추가될 예정이다.


2. C# Windows Forms 

- C# Windows Forms은 간단히 말해서 Widows GUI 프로그래밍을 위한 툴(?) 이라 생각하면 된다!! 

2-1. Windows Forms 시작

(1) windows Forms 만들기

새 프로젝트 만들기 → windows Forms 앱 만들기

 

(2) 초기화면 및 코드

초기화면

- windows Forms를 만들고 초기화면이 나오기까지 약간의 대기시간이 필요하다. 

- 'Form'은 사용자가 GUI 환경에서 다양한 기능을 추가하기 위한 '도화지' 라고 생각하면 된다.

코드 화면

- 초기화면에서 코딩을 하기 위한 화면으로 넘어가기 위해서는 Form에서 우클릭 후 '코드 보기'를 누르거나 단축키 [Ctrl + Alt + 0]을 누르면 된다.

 

(3) GUI 기본 구성 항목 

- 우측에 있는 도구 상자의 다양한 항목을 Drag & Drop을 통해 Form에 다양한 기능을 추가해 놓은 상태

- 물론 이렇게 구성만 한다고 기능이 동작하는 것이 아닌 해당 항목을 더블클릭하여서 관련 코드를 입력해 주어야 한다.

위의 button1을 더블클릭 하면 나오는 화면

- 위의 도구상자에서 button을 드래그 앤 드롭 후 더블클릭을 하면 코드화면에 button1_Click() 함수가 추가된다.

※ 만약 더블클릭을 잘못해서 사용하지 않을 항목이 위와같이 코드가 생성되었다면 함부로 코드를 지우면 안된다. (오류 발생) → 그냥 코드가 있는채로 가만히 놔 두던가, GUI에서 해당 항목을 삭제한 후 코드를 삭제해보도록 한다. 만일 후자의 방법으로 해도 오류가 발생하는 경우는 그냥 코드를 놔두는 방향으로 추천한다... 

 


2-2. 이미지 파일을 열기 위한 Windows Form 작성(GUI)

(1) Form1 Name 및 Text, Color 변경

- Form1에서 우클릭 후 속성창에서 Name과 Text, Color 등을 변경한다.

- 중요한 기능을 네이밍하는것은 프로그래밍을 잘하기 위한 중요한 부분중에 하나이기 때문에 사용자나 작업자가 알아보기 쉽고, 이해하기 쉬운 네이밍을 짓는 연습이 필요하다.

✔ Name : MainForm

✔ Text : Gray Scale Image Processing Beta 2

✔ BackColor : GradientlnactiveCaption

 

(2) MenuStrip, PictureBox 생성 및 속성 변경

- 도구상자에서 MenuStrip을 Drag & Drop 후 아래의 사진과 같이 입력한다.

- 도구상자에서 PictureBox를 드래그 앤 드롭 후 속성창에서 이름을 변경하여 준다.

✔ Name : PB_OutImage

- PictureBox는 openImage와 displayImage를 보여줄 '액자'라고 생각하면 된다.

 

(3) OpenFileDialog 추가하기

- 어떠한 프로그램에서 파일 - 열기를 누르면 뜨는 창을 우리들은 쉽게 상상할 수 있다.

- 이러한 창을 C#의 Windows Form에선 쉽게 구현할 수 있다.

(옛날에는 이러한 창을 구성할라면 코드가 천줄가량이 필요했다고 한다..)

- 도구상자에서 OpenFileDialog를 드래그 앤 드롭을 한다.

하단에 openFileDialog1이 추가된 것을 알 수 있다.

- GUI 환경에선 드래그 앤 드롭까지만 하고 나머지는 코딩을 통해 해결할 예정이다..


3. 이미지 파일 열기(Open) 및 표시(Display) 하기

3-1. 전역 변수 선언

static byte[,] inImage = null, outImage = null;
static int inH, inW, outH, outW;
static string fileName;
static Bitmap paper;

- 사용자 정의 함수부에서 자주 사용될 변수들은 전역변수로 미리 선언해 둔다.

- 본문의 위에 있는 영상처리 프로그램 구성도를 참고해서 inImage, outImage와 넓이와 폭을 나타내는 변수들을 전역변수로 선언하였다.


3-2. OpenImage

            // ofd : 파일을 담는 변수, new는 객체지향적인 특성상 붙혀준다.
            OpenFileDialog ofd = new OpenFileDialog();
            if (ofd.ShowDialog() == DialogResult.Cancel)
                return;
            fileName = ofd.FileName;
            BinaryReader br = new BinaryReader(File.Open(fileName, FileMode.Open));

            // (중요!!) 이미지의 폭과 높이 
            long fsize = new FileInfo(fileName).Length;
            inH = inW = (int)Math.Sqrt(fsize); // RAW 파일은 가로세로 길이가 같다.
            // 메모리 할당
            inImage = new byte[inH, inW];
            // 파일 --> 메모리
            for (int i = 0; i < inH; i++)
            {
                for (int k = 0; k < inW; k++)
                {
                    inImage[i, k] = br.ReadByte();
                }
            }
            br.Close();
            equalImage(); 
            // 어떨때는 inImage를 display하고 어떨때는 outImage를 display하면 
            // 코드가 복잡해지고 버그의 발생이 많아질 우려가 있기 때문에
            // openImage와 동일한 Image를 outImage에 display한다.

- GUI에서 드래그 앤 드롭했던 OpenFileDialog를 본 코드에서 객체를 호출하고 생성한다.

- OpenFileDialog 창을 통해 파일을 열게되면 해당 파일 경로는 fileName의 변수에 저장된다.

- RAW 이미지 파일은 가로와 세로의 길이가 같기 때문에 Math 클래스의 Sqrt 매서드를 이용해서 길이를 산출한다.

- 그리고 BinaryReader를 통해 해당 파일의 값(Byte)을 읽어서 inImage에 차곡 차곡 저장한다.

(2중 for문을 통해 inH * inW크기의 Byte 타입의 데이터를 저장한다)


3-3. DisplayImage

            //  크기 지정
            paper = new Bitmap(outH, outW); // 종이
            PB_OutImage.Size = new Size(outH, outW); // 액자
            this.Size = new Size(outH + 40, outW + 110);  // 벽(윈도우창)

            Color pen;
            for (int i = 0; i < outH; i++)
            {
                for (int k = 0; k < outW; k++)
                {
                    byte ink = outImage[i, k];
                    // 펜에 잉크 묻히기, RGB 3색이 같아야 회색조
                    pen = Color.FromArgb(ink, ink, ink);
                    paper.SetPixel(k, i, pen);
                }
            }
            PB_OutImage.Image = paper; // 액자에 종이 걸기

- 이번 프로젝트에서 만들고자 하는 프로그램은 Gray Scale Image Processing이기 때문에 RGB의 색상의 값이 동일한 회색조로 표현될 예정이다. 따라서 FromArgb()의 값은 모두 동일한 변수(ink)로 넣어준다.


3-4. equalmage

            // 이미지를 열지 않았으면 영상처리 불가
            if (inImage == null) return;
            // 중요 !! 출력 영상의 크기를 결정 --> 알고리즘에 따라 다름
            outH = inH;
            outW = inW;
            // 출력 영상 메모리 할당
            outImage = new byte[outH, outW];
            // ** 영상처리 알고리즘 **
            for (int i = 0; i < inH; i++)
            {
                for (int k = 0; k < inW; k++)
                {
                    outImage[i, k] = inImage[i, k];
                }
            }
            ///////////////////////////
            displayImage();

- 알고리즘에 따라 출력 이미지의 크기(outH, outW)가 달라진다. 

→ 아주 간단한 예로, 확대의 경우는 출력 이미지의 크기가 처음 이미지의 크기보다 더 커지기 때문에 outH와 outW의 값은 위의 코드와는 달라진다.

 

✔ 앞으로 다양한 영상처리 알고리즘을 작성하고 다양한 이미지 처리 및 가공 기능을 추가할텐데 모두다 위와 같은 형태를 기본으로 하고 조금씩 수정할 예정이다.


4. 결과

- 파일 → 열기 후 RAW 확장자를 가진 이미지 파일을 열면 아래와 같이 이미지가 보여지는것을 알 수 있다.

- 앞으로 파일을 열고 해당 사진을 다양한 기법(화소점 처리, 기하학 처리, 히스토그램 처리, 화소영역 처리)으로 이미지를 가공하고 편집할 예정이다.

단양 패러글라이딩 타기 전!!

댓글