수학적 영상처리
C#.net : Lab + Otsu with EmguCV
제갈티
2025. 2. 19. 14:04
using System;
using System.Windows.Forms;
using System.Drawing;
using Emgu.CV;
using Emgu.CV.Structure;
using Emgu.CV.CvEnum;
using Emgu.CV.Util;
namespace WinFormsApp2
{
public partial class Form1 : Form
{
private PictureBox originalImageBox;
private PictureBox processedImageBox;
private Button loadButton;
public Form1()
{
InitializeComponent();
this.Text = "Image Processing with EmguCV";
this.Size = new Size(1000, 600);
}
private void LoadButton_Click(object sender, EventArgs e)
{
using (OpenFileDialog openFileDialog = new OpenFileDialog())
{
openFileDialog.Filter = "Image Files|*.jpg;*.jpeg;*.png;*.bmp;*.tif";
openFileDialog.Title = "Select an Image";
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
try
{
// Load the original image
Mat originalImage = CvInvoke.Imread(openFileDialog.FileName, ImreadModes.Color);
// Display original image
originalImageBox.Image = originalImage.ToBitmap();
// Process the image
Mat processedImage = ProcessImage(originalImage);
// Display processed image
processedImageBox.Image = processedImage.ToBitmap();
}
catch (Exception ex)
{
MessageBox.Show($"Error processing image: {ex.Message}", "Error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}
private Mat ProcessImage(Mat originalImage)
{
// Convert BGR to Lab color space
Mat labImage = new Mat();
CvInvoke.CvtColor(originalImage, labImage, ColorConversion.Bgr2Lab);
// Split the Lab image into L, a, and b channels
VectorOfMat labChannels = new VectorOfMat();
CvInvoke.Split(labImage, labChannels);
// Get the 'a' channel (index 1)
Mat aChannel = labChannels[1];
// Apply Otsu thresholding on the 'a' channel
Mat binaryImage = new Mat();
CvInvoke.Threshold(aChannel, binaryImage, 0, 255,
ThresholdType.Binary | ThresholdType.Otsu);
return binaryImage;
}
private void Form1_Load(object sender, EventArgs e)
{
//filename = @"C:\Users\user1\Pictures\473323273_586319737608833_8471197295915664510_n\474496606_588482517392555_4021026081075372739_n.jpg";
}
}
}
- Form1.cs
namespace WinFormsApp2
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
// Original Image PictureBox
originalImageBox = new PictureBox
{
Location = new Point(20, 20),
Size = new Size(450, 450),
SizeMode = PictureBoxSizeMode.Zoom,
BorderStyle = BorderStyle.FixedSingle
};
// Processed Image PictureBox
processedImageBox = new PictureBox
{
Location = new Point(500, 20),
Size = new Size(450, 450),
SizeMode = PictureBoxSizeMode.Zoom,
BorderStyle = BorderStyle.FixedSingle
};
// Load Image Button
loadButton = new Button
{
Text = "Load Image",
Location = new Point(20, 490),
Size = new Size(120, 40)
};
loadButton.Click += LoadButton_Click;
// Add controls to form
this.Controls.Add(originalImageBox);
this.Controls.Add(processedImageBox);
this.Controls.Add(loadButton);
SuspendLayout();
//
// Form1
//
AutoScaleDimensions = new SizeF(9F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 450);
Name = "Form1";
Text = "Form1";
Load += Form1_Load;
ResumeLayout(false);
}
#endregion
}
}
- Designer.cs