Edycja obrazu w czasie rzeczywistym

Odpowiedz Nowy wątek
2011-08-24 11:48
0

Witam, kolejny raz zwracam się z głupim zapewne pytaniem, ale niestety wymiękłem na początkowym etapie pisania aplikacji. Otóż muszę napisać aplikację poddającą dany obrazek różnego rodzaju obróbkom, filtrowaniu koloru, zmiany rozmiaru, wyszukiwania obiektów na nim. Założenie jednak jest takie, żebym na bieżąco mógł oglądać rezultaty dokonanych kolejno operacji na bitmapie, a nie od razu po uruchomieniu aplikacji widzieć gotowy obraz po wszystkich przeróbkach. I tak np. jeśli uruchomię poniższy kod:

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 AForge;
using AForge.Imaging;
using AForge.Imaging.Filters;
 
namespace final
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
 
        private void zamknijToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }
 
        private void otworzToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    ProcessImage((Bitmap)Bitmap.FromFile(openFileDialog.FileName).Clone());
                }
                catch
                {
                    MessageBox.Show("Failed loading selected image file.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }
 
        private void ProcessImage(Bitmap bitmap)
        {
                ResizeBilinear filter1 = new ResizeBilinear(640, 480);
                Bitmap sourceImageRS = filter1.Apply(bitmap);
                ColorFiltering filter2 = new ColorFiltering();
                filter2.Red = new IntRange(0, 64);
                filter2.Green = new IntRange(0, 64);
                filter2.Blue = new IntRange(0, 64);
                filter2.FillOutsideRange = false;
                Bitmap CFimage = filter2.Apply(sourceImageRS);
                bitmap = CFimage;
                pictureBox1.Image = bitmap;
         }
    }
}

Otrzymuję gotowy obraz - sformatowany do rozdzielczości 640x480 oraz poddany obróbce filtracji kolorów. Jeśli jednak chcę najpierw otrzymać obraz sformatowany, a następnie za pomocą checkboxa uruchomić na nim filtrację kolorów z obrazem nic się nie dzieje, próbuję uzyskać to poniższym kodem:

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 AForge;
using AForge.Imaging;
using AForge.Imaging.Filters;
 
namespace final
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
 
        private void zamknijToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }
 
        private void otworzToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    ProcessImage((Bitmap)Bitmap.FromFile(openFileDialog.FileName).Clone());
                }
                catch
                {
                    MessageBox.Show("Failed loading selected image file.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }
 
        private void ProcessImage(Bitmap bitmap)
        {
                ResizeBilinear filter1 = new ResizeBilinear(640, 480);
                Bitmap sourceImageRS = filter1.Apply(bitmap);
                bitmap = sourceImageRS;
                if (checkBox1.Checked)
                {
                    ColorFiltering filter2 = new ColorFiltering();
                    filter2.Red = new IntRange(0, 64);
                    filter2.Green = new IntRange(0, 64);
                    filter2.Blue = new IntRange(0, 64);
                    filter2.FillOutsideRange = false;
                    Bitmap CFimage = filter2.Apply(bitmap);
                    bitmap = CFimage;
                }
                pictureBox1.Image = bitmap;
          }
    }
}

Jak sprawić, żeby poszczególne metody obróbki obrazu (filtracja koloru to tylko jedna z kilku, których planuję użyć) działały "na bieżąco" na wyświetlanym w picturebox obrazku?

Byłbym bardzo wdzięczny za odpowiedź. Na upartego, mógłbym napisać sprawozdanie z poszczególnych etapów obróbki obrazu za pomocą różnych metod, ale za każdym razem musiałbym zmieniać kod programu, a biorąc pod uwagę, że metod jest kilka, a zdjęć do analizy sporo, byłoby to bardzo czasochłonne.

edytowany 1x, ostatnio: okube, 2011-08-24 11:49

Pozostało 580 znaków

2011-08-24 15:32
0

Nie obsługujesz w ogóle zdarzenia checkBox1 (chyba CheckedChanged).

ProcessImage((Bitmap)Bitmap.FromFile(openFileDialog.FileName).Clone());
nie klonuj tylko:
ProcessImage(Bitmap.FromFile(openFileDialog.FileName));

No i nieużywane bitmapy pasowałoby zwolnić (metoda Dispose()).

edytowany 1x, ostatnio: chrabeusz, 2011-08-24 15:37

Pozostało 580 znaków

2011-08-24 15:46
0

Ach zapomniałem skasować Clone(); pierwotnie w ogóle go tam nie było, później próbowałem zrobić to na bazie aplikacji obrabiającej obraz przetwarzany wprost z kamery, stad to się tam pojawiło, jednak bez tego program nie działał, tak jak powinien również. Checkbox uruchamiany w ten sposób w aplikacji z kamerą mi działał, niemniej jednak spróbuję to zrobić tak, jak sugerujesz.

W którym konkretnie miejscu zwalniać bitmapy? W samym warunku z checkboxem, przed wpisaniem bitmapy "bitmap" w Picturebox1?

edytowany 1x, ostatnio: okube, 2011-08-24 15:47

Pozostało 580 znaków

2011-08-24 23:44
0

Gwoli ścisłości: główny problem to brak obsługi wspomnianego zdarzenia. Clone() i Dispose() to szczegóły bardziej.
Checkbox z kamerą działał, bo miałeś pewnie jakiegoś timera który uruchamiał ProcessImage.
Bitmapę zwolnij przy ładowaniu nowej (jeśli jakaś była) i przy odznaczaniu checkboxa.
Aha, i będziesz jeszcze potrzebował gdzieś trzymać bitmapę oryginalną, tak żeby do niej wrócić gdy odznaczysz checkboxa.

Pozostało 580 znaków

2011-08-27 10:57
0

Dzięki wielkie za pomoc, uprzedziłeś poza tym moje pytanie od powrót do "normalnej" bitmapy, po odhaczeniu checkboxa, teraz aplikacja działa tak, jak powinna, dziękuję raz jeszcze.

Pozdrawiam :)

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0