C# OpenCvSharp 图像校正

这篇具有很好参考价值的文章主要介绍了C# OpenCvSharp 图像校正。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

效果

代码

下载


效果

opencvsharp 矩形检测,OpenCV,C#,c#,opencv,计算机视觉,C# 图像校正

代码

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 OpenCvSharp;
using OpenCvSharp.Extensions;

namespace OpenCvSharp_图像校正
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        string img = "test.png";

        private void Form1_Load(object sender, EventArgs e)
        {
            pictureBox1.Image = new Bitmap(img);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Mat src = new Mat(img);

            //转化为灰度图
            //Cv2.CvtColor(src, src, ColorConversionCodes.RGB2GRAY);

            InputArray kernel = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(3, 3));
            Cv2.MorphologyEx(src, src, MorphTypes.Close, kernel, new OpenCvSharp.Point(-1, -1), 3);
            //Cv2.ImShow("MorphologyEx", src);

            /*
                ksize,高斯内核大小,ksize.width和ksize.height必须是正奇数,两者可以不相同,值越大越模糊
                sigmaX,Y轴方向的标准差,值越大越模糊
                sigmaY,X轴方向的标准差,值越大越模糊
             */
            Cv2.GaussianBlur(src, src, new OpenCvSharp.Size(11, 11), 2, 2);
            //Cv2.ImShow("GaussianBlur", src);

            //Canny边缘检测
            Mat canny_Image = new Mat();
            Cv2.Canny(src, canny_Image, 10, 30, 3, false);

            OpenCvSharp.Point[][] contours;
            HierarchyIndex[] hierarchly;
            /*
              findContours找到轮廓
              第一个参数:单通道图像矩阵,可以是灰度图,但更常用的是二值图像,一般是经过Canny、拉普拉斯等边缘检测算子处理过的二值图像;
              第二个参数:contours 
              第三个参数:hierarchy
              第四个参数:轮廓的检索模式
                      取值一:CV_RETR_EXTERNAL 只检测最外围轮廓,包含在外围轮廓内的内围轮廓被忽略
                      取值二:CV_RETR_LIST     检测所有的轮廓,包括内围、外围轮廓,但是检测到的轮廓不建立等级关系,彼此之间独立,没有等级关系,这就意味着这个检索模式下不存在父轮廓或内嵌轮廓,所以hierarchy向量内所有元素的第3、第4个分量都会被置为-1,具体下文会讲到
                      取值三:CV_RETR_CCOMP    检测所有的轮廓,但所有轮廓只建立两个等级关系,外围为顶层,若外围内的内围轮廓还包含了其他的轮廓信息,则内围内的所有轮廓均归属于顶层
                      取值四:CV_RETR_TREE     检测所有轮廓,所有轮廓建立一个等级树结构。外层轮廓包含内层轮廓,内层轮廓还可以继续包含内嵌轮廓。
              第五个参数:轮廓的近似方法
                      取值一:CV_CHAIN_APPROX_NONE   保存物体边界上所有连续的轮廓点到contours向量内
                      取值二:CV_CHAIN_APPROX_SIMPLE 仅保存轮廓的拐点信息,把所有轮廓拐点处的点保存入contours向量内,拐点与拐点之间直线段上的信息点不予保留
                      取值三和四:CV_CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS使用teh-Chinl chain 近似算法
              第六个参数:Point偏移量,所有的轮廓信息相对于原始图像对应点的偏移量,相当于在每一个检测出的轮廓点上加上该偏移量,且Point可以是负值。不填为默认不偏移Point()
             */
            Cv2.FindContours(canny_Image, out contours, out hierarchly,
                RetrievalModes.External,
                ContourApproximationModes.ApproxSimple,
                new OpenCvSharp.Point(0, 0));

            if (contours.Length == 0)
            {
                MessageBox.Show("边缘检测失败");
                return;
            }

            Random rnd = new Random();
            Scalar color;
            color = new Scalar(0, 255, 0);
            for (int i = 0; i < contours.Length; i++)
            {
                color = new Scalar(rnd.Next(0, 255), rnd.Next(0, 255), rnd.Next(0, 255));
                Cv2.DrawContours(src, contours, i, color, 2, LineTypes.Link4);
            }
            //Cv2.ImShow("contours", src);

            //求出面积最大的轮廓
            double max_area = 0.0;
            double currentArea = 0.0;
            OpenCvSharp.Point[] max_contour = null;
            for (int i = 0; i < contours.Length; i++)
            {
                currentArea = Cv2.ContourArea(contours[i]);
                if (currentArea > max_area)
                {
                    max_area = currentArea;
                    max_contour = contours[i];
                }
            }

            //多边形拟合凸包的四个顶点
            OpenCvSharp.Point[] hull = Cv2.ConvexHull(max_contour);
            double epsilon = 0.02 * Cv2.ArcLength(max_contour, true);
            OpenCvSharp.Point[] approx = Cv2.ApproxPolyDP(hull, epsilon, true);

            if (approx.Length != 4)
            {
                MessageBox.Show("拟合凸包的四个顶点失败");
                return;
            }

            Scalar scalar2 = new Scalar(0, 255, 255);

            Cv2.Line(src, approx[0], approx[1], scalar2, 1, LineTypes.Link4);
            Cv2.Line(src, approx[1], approx[2], scalar2, 1, LineTypes.Link4);
            Cv2.Line(src, approx[2], approx[3], scalar2, 1, LineTypes.Link4);
            Cv2.Line(src, approx[3], approx[0], scalar2, 1, LineTypes.Link4);

            //排序
            Array.Sort(approx, (cs1, cs2) =>
            {
                if (cs1 != null && cs1 != null)
                {
                    if (cs1.Y > cs2.Y)
                        return 1;
                    else if (cs1.Y == cs2.Y)
                    {
                        if (cs1.X < cs2.X)
                            return 1;
                        else return -1;
                    }
                    else
                        return -1;
                }
                return 0;

            });

            //算法找出的角点
            OpenCvSharp.Point2f[] srcPt = new OpenCvSharp.Point2f[4];
            srcPt[0] = approx[0];
            srcPt[1] = approx[1];
            srcPt[2] = approx[3];
            srcPt[3] = approx[2];

            //最小外接矩形
            RotatedRect rect = Cv2.MinAreaRect(srcPt);
            Rect box = rect.BoundingRect();
            OpenCvSharp.Point2f[] dstPt = new OpenCvSharp.Point2f[4];

            dstPt[0].X = box.X;
            dstPt[0].Y = box.Y;

            dstPt[1].X = box.X + box.Width;
            dstPt[1].Y = box.Y;

            dstPt[2].X = box.X + box.Width;
            dstPt[2].Y = box.Y + box.Height;

            dstPt[3].X = box.X;
            dstPt[3].Y = box.Y + box.Height;

            Mat src2 = new Mat(img);
            Mat final = new Mat();
            Mat warpmatrix = Cv2.GetPerspectiveTransform(srcPt, dstPt);//获得变换矩阵
            Cv2.WarpPerspective(src2, final, warpmatrix, src.Size());//投射变换,将结果赋给final

            Bitmap temp = BitmapConverter.ToBitmap(final);

            pictureBox2.Image = temp;

            DrawLine(srcPt, dstPt);

            //Application.DoEvents();
            //System.Threading.Thread.Sleep(1000);
            //pictureBox2.Image = CutImage(temp, (int)p2f[0].X, (int)p2f[0].Y, (int)p2f[2].X, (int)p2f[2].Y);

        }

        void DrawLine(OpenCvSharp.Point2f[] srcPt, OpenCvSharp.Point2f[] dstPt)
        {
            Bitmap bmp = new Bitmap(img);
            Graphics g = Graphics.FromImage(bmp);

            Pen pen = new Pen(Color.Red, 3);
            Pen pen2 = new Pen(Color.Blue, 3);

            g.DrawLine(pen, srcPt[0].X, srcPt[0].Y, srcPt[1].X, srcPt[1].Y);
            g.DrawLine(pen, srcPt[1].X, srcPt[1].Y, srcPt[2].X, srcPt[2].Y);
            g.DrawLine(pen, srcPt[2].X, srcPt[2].Y, srcPt[3].X, srcPt[3].Y);
            g.DrawLine(pen, srcPt[3].X, srcPt[3].Y, srcPt[0].X, srcPt[0].Y);

            g.DrawLine(pen2, dstPt[0].X, dstPt[0].Y, dstPt[1].X, dstPt[1].Y);
            g.DrawLine(pen2, dstPt[1].X, dstPt[1].Y, dstPt[2].X, dstPt[2].Y);
            g.DrawLine(pen2, dstPt[2].X, dstPt[2].Y, dstPt[3].X, dstPt[3].Y);
            g.DrawLine(pen2, dstPt[3].X, dstPt[3].Y, dstPt[0].X, dstPt[0].Y);

            pictureBox1.Image = bmp;

        }

        /// <summary>
        /// 剪裁图片
        /// </summary>
        /// <param name="src">原图片</param>
        /// <param name="left">左坐标</param>
        /// <param name="top">顶部坐标</param>
        /// <param name="right">右坐标</param>
        /// <param name="bottom">底部坐标</param>
        /// <returns>剪裁后的图片</returns>
        public Image CutImage(Image src, int left, int top, int right, int bottom)
        {
            Bitmap srcBitmap = new Bitmap(src);
            int width = right - left;
            int height = bottom - top;
            Bitmap destBitmap = new Bitmap(width, height);
            using (Graphics g = Graphics.FromImage(destBitmap))
            {
                g.Clear(Color.Transparent);
                //设置画布的描绘质量         
                g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
                g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                g.DrawImage(srcBitmap, new Rectangle(0, 0, width, height), left, top, width, height, GraphicsUnit.Pixel);
            }
            return destBitmap;
        }
    }

下载

源码下载

 文章来源地址https://www.toymoban.com/news/detail-614828.html

到了这里,关于C# OpenCvSharp 图像校正的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C#使用OpenCv(OpenCVSharp)图像处理实例:亮度、对比度、灰度

    本文实例演示C#语言中如何使用OpenCv(OpenCVSharp)对图像进行亮度、对比度、灰度处理。 目录 亮度和对比度原理 灰度 实例 图像亮度通俗理解便是图像的明暗程度,数字图像 f(x,y) = i(x,y) r(x, y) ,如果灰度值在[0,255]之间,则 f 值越接近0亮度越低,f 值越接近255亮度越

    2024年02月13日
    浏览(47)
  • C# OpenCvSharp 轮廓检测

    目录 效果 代码 下载  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 OpenCvSharp; using OpenCvSharp.Extensions; namespace OpenCvSharp_轮廓检测 {     public partial class Form1 : Form     {        

    2024年04月15日
    浏览(35)
  • C#图像处理-OpenCVSharp教程:OpenCVSharp与EmguCV的比较与介绍

    C#图像处理-OpenCVSharp教程:OpenCVSharp与EmguCV的比较与介绍 图像处理在计算机视觉和计算机图形学等领域发挥着至关重要的作用。本教程将介绍在C#中使用OpenCVSharp和EmguCV这两个流行的图像处理库,它们提供了丰富的功能和强大的性能。 一、OpenCVSharp介绍与特点 OpenCVSharp是OpenCV的

    2024年02月21日
    浏览(28)
  • c# OpenCvSharp 检测(斑点检测、边缘检测、轮廓检测)(五)

    在C#中使用OpenCV进行图像处理时,可以使用不同的算法和函数来实现斑点检测、边缘检测和轮廓检测。 斑点检测 边缘检测 轮廓检测 斑点检测是指在图像中找到明亮或暗的小区域(通常表示为斑点),并标记它们的位置。可以使用OpenCV中的函数SimpleBlobDetector来实现斑点检测。

    2024年02月04日
    浏览(33)
  • C#使用OpenCv(OpenCVSharp)教程详解

    本篇讲解C#中如何使用OpenCV(OpenCVSharp) 目录 前言 OpenCVSharp安装 OpenCVSharp使用 实例读取图像并显示

    2024年02月13日
    浏览(32)
  • c# OpenCvSharp读取、显示和写入图像(二)

            读取、显示和写入图像是图像处理和计算机视觉的基础。即使在裁剪、调整大小、旋转或应用不同的滤镜来处理图像时,您也需要先读取图像。因此,掌握这些基本操作非常重要。 imread()读取图像 imshow()在窗口中显示图像 imwrite()将图像保存到文件目录里 我们将使

    2024年02月02日
    浏览(54)
  • c# OpenCvSharp图像裁剪、调整大小、旋转、透视(三)

    图像裁剪、调整大小、旋转、透视图像处理基本操作。 croppedImage 图像裁剪 Cv2.Resize() 调整图像大小 图像旋转 Cv2.Rotate()旋转 Cv2.Flip()翻转 Cv2.WarpAffine()任意角度旋转 Cv2.GetAffineTransform()透视 Rect rect = new Rect(x, y, width, height); // x, y 为起始坐标,width, height 为裁剪宽高 参数 说明

    2024年02月04日
    浏览(23)
  • C#图像处理-使用OpenCVSharp读取或修改图像像素值

    图像处理是计算机视觉领域的重要应用之一,而OpenCV是一个强大且广泛使用的开源计算机视觉库。在C#中,我们可以通过OpenCVSharp库来实现图像处理的各种功能,包括读取和修改图像像素值。本文将介绍如何使用OpenCVSharp来读取和修改图像像素值,并提供相应的源代码。 首先,

    2024年04月28日
    浏览(27)
  • C# OpenCvSharp Yolov8 Detect 目标检测

    目录 效果 模型信息 项目 代码 下载  Model Properties ------------------------- date:2023-09-05T13:17:15.396588 description:Ultralytics YOLOv8n model trained on coco.yaml author:Ultralytics task:detect license:AGPL-3.0 https://ultralytics.com/license version:8.0.170 stride:32 batch:1 imgsz:[640, 640] names:{0: \\\'person\\\', 1: \\\'b

    2024年02月02日
    浏览(35)
  • C# OpenCvSharp Yolov8 Cls 图像分类

    目录 效果 项目 模型信息 代码 下载  Model Properties ------------------------- date:2023-09-07T17:11:37.011156 description:Ultralytics YOLOv8n-cls model trained on ../datasets/imagenet author:Ultralytics task:classify license:AGPL-3.0 https://ultralytics.com/license version:8.0.172 stride:1 batch:1 imgsz:[640, 640] names:{0:

    2024年02月07日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包