algorytm.org

Implementacja w C#



Baza Wiedzy
wersja offline serwisu przeznaczona na urządzenia z systemem Android
Darowizny
darowiznaWspomóż rozwój serwisu
Nagłówki RSS
Artykuły
Implementacje
Komentarze
Forum
Bookmarki






Sonda
Implementacji w jakim języku programowania poszukujesz?

Histogram - wyrównywanie - Implementacja w C#
Ocena użytkownikóww: *****  / 0
SłabyŚwietny
Nadesłany przez Tomasz Lubiński, 15 listopada 2019 21:19
Kod przedstawiony poniżej przedstawia główną część rozwiązania problemu.
Pobierz pełne rozwiązanie.

Jeżeli nie odpowiada Ci sposób formatowania kodu przez autora skorzystaj z pretty printer'a i dostosuj go automatycznie do siebie.

Histogram/Form1.cs:
//Wyznaczanie i wyrównywanie Histogramu
//(c) 2019 by Tomasz Lubinski
//www.algorytm.org

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

namespace Histogram
{
    public partial class Form1 : Form
    {
        private int[] red = null;
        private int[] green = null;
        private int[] blue = null; 

        /// <summary>
        /// Zainicjuj
        /// </summary>
        public Form1()
        {
            InitializeComponent();
        }

        /// <summary>
        /// Wczytaj obraz
        /// </summary>
        private void wczytaj_Click(object sender, EventArgs e)
        {
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.Title = "Otwórz obraz";
            dlg.Filter = "Obrazy (*.jpg;*.gif;*.png;*.bmp)|*.jpg;*.gif;*.png;*.bmp";
            if (dlg.ShowDialog() == DialogResult.OK)
            {
                //Wczytaj plik
                picture.Image = new Bitmap(dlg.OpenFile());
                picture.Height = picture.Image.Height;
                picture.Width = picture.Image.Width;
                this.ClientSize = new System.Drawing.Size(Math.Max(picture.Width + 30, 345), picture.Height + 155);

                //Oblicz histogram
                red = new int[256];
                green = new int[256];
                blue = new int[256];                
                for (int x = 0; x < picture.Width; x++)
                {
                    for (int y = 0; y < picture.Height; y++)
                    {
                        Color pixel = ((Bitmap)picture.Image).GetPixel(x, y);
                        red[pixel.R]++;
                        green[pixel.G]++;
                        blue[pixel.B]++;
                    }
                }

                //Wyswietl histogram na wykresie
                chart.Series["red"].Points.Clear();
                chart.Series["green"].Points.Clear();
                chart.Series["blue"].Points.Clear();
                for (int i = 0; i < 256; i++)
                {
                    chart.Series["red"].Points.AddXY(i, red[i]);
                    chart.Series["green"].Points.AddXY(i, green[i]);
                    chart.Series["blue"].Points.AddXY(i, blue[i]);
                }
                chart.Invalidate();
            }
            dlg.Dispose();
        }

        /// <summary>
        /// Oblicza tablice LUT dla histogramu podanej składowej
        /// </summary>
        /// <param name="values">histogram dla składowej</param>
        /// <returns>tablica LUT do wyrównania histogramu</returns>
        private int[] calculateLUT(int[] values, int size)
        {
            //poszukaj wartości minimalnej - czyli pierwszej niezerowej wartosci dystrybuanty
            double minValue = 0;
            for (int i = 0; i < 256; i++)
            {
                if (values[i] != 0)
                {
                    minValue = values[i];
                    break;
                }
            }

            //przygotuj tablice zgodnie ze wzorem
            int[] result = new int[256];
            double sum = 0;
            for (int i = 0; i < 256; i++)
            {
                sum += values[i];
                result[i] = (int)(((sum - minValue) / (size - minValue)) * 255.0);
            }

            return result;
        }

        /// <summary>
        /// Wyrownywanie Histogramu
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void process_Click(object sender, EventArgs e)
        {
            //Sprawdz czy wczytano obraz
            if (red == null)
            {
                return;
            }

            //Tablice LUT dla skladowych
            int[] LUTred = calculateLUT(red, picture.Image.Width * picture.Image.Height);
            int[] LUTgreen = calculateLUT(green, picture.Image.Width * picture.Image.Height);
            int[] LUTblue = calculateLUT(blue, picture.Image.Width * picture.Image.Height);

            //Przetworz obraz i oblicz nowy histogram
            red = new int[256];
            green = new int[256];
            blue = new int[256];
            Bitmap oldBitmap = (Bitmap)picture.Image;
            Bitmap newBitmap = new Bitmap(oldBitmap.Width, oldBitmap.Height, PixelFormat.Format24bppRgb);
            for (int x = 0; x < picture.Width; x++)
            {
                for (int y = 0; y < picture.Height; y++)
                {
                    Color pixel = oldBitmap.GetPixel(x, y);
                    Color newPixel = Color.FromArgb(LUTred[pixel.R], LUTgreen[pixel.G], LUTblue[pixel.B]);
                    newBitmap.SetPixel(x, y, newPixel);
                    red[newPixel.R]++;
                    green[newPixel.G]++;
                    blue[newPixel.B]++;
                }
            }
            picture.Image = newBitmap;

            //Wyswietl histogram na wykresie
            chart.Series["red"].Points.Clear();
            chart.Series["green"].Points.Clear();
            chart.Series["blue"].Points.Clear();
            for (int i = 0; i < 256; i++)
            {
                chart.Series["red"].Points.AddXY(i, red[i]);
                chart.Series["green"].Points.AddXY(i, green[i]);
                chart.Series["blue"].Points.AddXY(i, blue[i]);
            }
            chart.Invalidate();
        }
    }
}
Dodaj komentarz