카테고리 없음

[C#] 10. 컬러이미지 영상처리 프로그램 [WinForm & SubForm]

쑨야미 2021. 4. 20. 15:46

컬러이미지는 RGB 각각에 해당하는 3개의 배열에 저장된다. (Raw 이미지는 1개의 배열)

따라서 Raw와 달리 파일을 불러올때도 Bitmap을 이용한다. ( Raw 이미지는 출력시에만 bitmap 이용)

그외에 원리는 Raw이미지 처리와 거의 비슷하다.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Day06_1_칼라_영상_처리_Beta1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        // 전역 변수
        byte[,,] inImage, outImage;
        int inH = 0, inW = 0, outH = 0, outW = 0;
        String fileName;
        Bitmap bitmap;
        static int RGB = 3, R = 0, G = 1, B = 2;

        private void 그레이스케일ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            greyScale();
        }

        private void 열기ToolStripMenuItem_Click_1(object sender, EventArgs e)
        {
            openImage();
        }

        private void ㅂToolStripMenuItem_Click(object sender, EventArgs e)
        {
            equalImage();
        }

        private void 밝게어둡게ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            addImage();
        }

        /// 메뉴 이벤트 함수

        private void 열기ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            openImage();
        }

        /// 공통 함수
        void openImage()
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.ShowDialog();
            fileName = ofd.FileName;
            // 파일 --> 비트맵
            bitmap = new Bitmap(fileName);
            // 중요! 입력메모리의 크기를 알아냄.
            inW = bitmap.Height;
            inH = bitmap.Width;
            // 입력 메모리 확보
            inImage = new byte[RGB, inH, inW];
            // 파일 --> 입력 메모리 로딩 (비트맵에 무물보)
            for (int i = 0; i < inH; i++)
                for (int k = 0; k < inW; k++)
                {
                    Color c = bitmap.GetPixel(i, k);
                    inImage[R, i, k] = c.R;
                    inImage[G, i, k] = c.G;
                    inImage[B, i, k] = c.B;
                }
            equalImage();
        }

        void displayImage()
        {
            // 비트맵 및 픽처박스 크기 조절
            bitmap = new Bitmap(outH, outW);
            pictureBox1.Size = new Size(outH, outW);
            this.Size = new Size(outH + 20, outW + 90);

            Color pen;// 비트맵에 콕콕 찍을 펜.
            for (int i = 0; i < outH; i++)
                for (int k = 0; k < outW; k++)
                {
                    byte dataR = outImage[R, i, k]; // 한점(=색상)
                    byte dataG = outImage[G, i, k]; // 한점(=색상)
                    byte dataB = outImage[B, i, k]; // 한점(=색상)
                    pen = Color.FromArgb(dataR, dataG, dataB); //펜에 잉크 묻힘
                    bitmap.SetPixel(i, k, pen); // 콕! 점찍기.
                }

            pictureBox1.Image = bitmap;
            toolStripStatusLabel1.Text = "크기:" + outH + "x" + outW;
        }

        /// 칼라 영상처리 함수
        void equalImage()
        {
            // 중요! 출력 이미지의 크기. --> 알고리즘에 의존.
            outH = inH;
            outW = inW;
            // 출력 이미지 메모리 할당
            outImage = new byte[RGB, outH, outW];
            /// 진짜! 영상처리 알고리즘을 구현
            for (int rgb = 0; rgb < RGB; rgb++)
                for (int i = 0; i < inH; i++)
                    for (int k = 0; k < inW; k++)
                    {
                        outImage[rgb, i, k] = inImage[rgb, i, k];
                    }
            displayImage();
        }

        void addImage()
        {
            // 중요! 출력 이미지의 크기. --> 알고리즘에 의존.
            outH = inH;
            outW = inW;
            // 출력 이미지 메모리 할당
            outImage = new byte[RGB, outH, outW];
            /// 진짜! 영상처리 알고리즘을 구현
            Form2 sub = new Form2();
            if (sub.ShowDialog() == DialogResult.Cancel)
                return;
            int value = (int)sub.nup_value.Value;


            for (int rgb = 0; rgb < RGB; rgb++)
                for (int i = 0; i < inH; i++)
                    for (int k = 0; k < inW; k++)
                    {
                        if ((inImage[rgb, i, k] + value) >= 255)
                            outImage[rgb, i, k] = 255;
                        else if ((inImage[rgb, i, k] + value) <= 0)
                            outImage[rgb, i, k] = 0;
                        else outImage[rgb, i, k] = (byte)(inImage[rgb, i, k] + value);

                    }
            displayImage();
        }
        void greyScale()
        {
            // 중요! 출력 이미지의 크기. --> 알고리즘에 의존.
            outH = inH;
            outW = inW;
            // 출력 이미지 메모리 할당
            outImage = new byte[RGB, outH, outW];
            /// 진짜! 영상처리 알고리즘을 구현

            for (int i = 0; i < inH; i++)
                for (int k = 0; k < inW; k++)
                {
                    int value = inImage[R, i, k] + inImage[G, i, k] + inImage[B, i, k];
                    value = (int)(value / 3.0);
                    outImage[R, i, k] = outImage[G, i, k] = outImage[B, i, k] = (byte)value;


                }
            displayImage();
        }

    }
}

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Day06_1_칼라_영상_처리_Beta1
{
    public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.OK;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.Cancel;
        }

        private void numericUpDown1_ValueChanged(object sender, EventArgs e)
        {

        }
    }
}