古今中外文史赏析

C#:图像分割与显示函数实现

2025-05-07  本文已影响0人  大龙10

1、分割函数:

GetImagePart方法实现主要逻辑:

2、边界检测方法:

3、程序

       private Mat originalMat;
      private void BtnOpen_Click(object sender, EventArgs e)
        {
            using (var openFileDialog = new OpenFileDialog())
            {
                openFileDialog.Filter = "Image Files|*.jpg;*.png;*.bmp";
                if (openFileDialog.ShowDialog() == DialogResult.OK)
                {
                    try
                    {
                        // 释放之前的图像资源
                        originalMat?.Dispose();
                        // 读取图像(BGR格式)
                        originalMat = Cv2.ImRead(openFileDialog.FileName, ImreadModes.Color);
                        if (originalMat.Empty())
                        {
                            MessageBox.Show("无法加载图像!");
                            return;
                        }
                        // 转换为RGB格式并显示
                      //  Cv2.CvtColor(originalMat, originalMat, ColorConversionCodes.BGR2RGB);
                        pictureBoxOriginal.Image = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(originalMat);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show($"加载图像出错: {ex.Message}");
                    }
                }
            }
        }

       public Mat GetImagePart(Mat sourceImage, int partNumber)
        {
            if (sourceImage.Empty())
                return null;

            using (Mat gray = new Mat())
            {
                Cv2.CvtColor(sourceImage, gray, ColorConversionCodes.BGR2GRAY);

                // 计算左右极点
                int x_left = FindEdge(gray, true);
                int x_right = FindEdge(gray, false);

                int totalWidth = x_right - x_left + 1;
                if (totalWidth < 10)
                    throw new ArgumentException("有效区域宽度不足10像素");

                // 计算分割参数
                int baseWidth = totalWidth / 10;
                int remainder = totalWidth % 10;
                List<Rect> segments = new List<Rect>();

                int currentRight = x_right;
                for (int i = 0; i < 10; i++)
                {
                    int width = baseWidth + (i < remainder ? 1 : 0);
                    int x = currentRight - width + 1;
                    segments.Add(new Rect(x, 0, width, sourceImage.Rows));
                    currentRight = x - 1;
                }

                // 验证参数有效性
                if (partNumber < 0 || partNumber >= segments.Count)
                    throw new ArgumentOutOfRangeException("分段编号应为0-9");

                Rect roi = segments[partNumber];
                return new Mat(sourceImage, roi);
            }
        }

        private int FindEdge(Mat gray, bool findLeft)
        {
            int edge = findLeft ? 0 : gray.Cols - 1;
            int step = findLeft ? 1 : -1;
            int end = findLeft ? gray.Cols : -1;

            for (int x = edge; x != end; x += step)
            {
                using (Mat col = gray.Col(x))
                {
                    if (Cv2.CountNonZero(col) > 0)
                    {
                        edge = x;
                        break;
                    }
                }
            }
            return edge;
        }


        private void button2_Click(object sender, EventArgs e)
        {
            using (Mat part = GetImagePart(originalMat, 3))
            {
                if (part != null)
                {
                    Bitmap bmp = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(part);
                    pictureBoxResult.Image?.Dispose();
                    pictureBoxResult.Image = bmp;
                }
            }
        }

4、运行结果

上一篇 下一篇

猜你喜欢

热点阅读