最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C#使用OpenCV剪切圖像中的圓形和矩形的示例代碼

 更新時間:2021年03月08日 11:25:07   作者:kiba518  
這篇文章主要介紹了C#使用OpenCV剪切圖像中的圓形和矩形,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下

前言

本文主要介紹如何使用OpenCV剪切圖像中的圓形和矩形。

準備工作

首先創(chuàng)建一個Wpf項目——WpfOpenCV,這里版本使用Framework4.7.2。

然后使用Nuget搜索【Emgu.CV】,如下圖。

這里的Emgu.CV選擇4.3.0.3890版本,然后安裝Emgu.CV和Emgu.CV.runtime.windows。

使用OPenCV剪切矩形

現(xiàn)在,我們進入項目,進行OPenCV的調(diào)用。

首先引入命名空間,如下:

using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.Structure;
using System.Drawing;
using System.Windows.Forms;

然后編寫矩形剪切函數(shù)——CutRectangleImage。

函數(shù)里,我們先將圖像進行縮放,這樣可以有效的減少檢測到的矩形數(shù)量。

再將圖片處理成灰度模式,然后再高斯模糊,再邊緣化。

然后,我們就可以在圖片里查找圖形輪廓了,當輪廓有三個頂點,那么它是三角形,如果有四個頂點,那么它是四邊形;我們要截取矩形,所以這里要加一個角度的判斷,四個角必須都在80-100度之間。

取到了頂點后,在依據(jù)頂點剪切圖片就可以了。

下面是截取矩形的代碼,代碼中只截取了寬度最大的那個矩形。

public void CutRectangleImage(string imagePath)
{
  Image<Bgr, Byte> src = new Image<Bgr, byte>(imagePath);
  int scale = 1;
  if (src.Width > 500)
  {
    scale = 2;
  }
  if (src.Width > 1000)
  {
    scale = 10;
  }
  if (src.Width > 10000)
  {
    scale = 100;
  }
  var size = new Size(src.Width / scale, src.Height / scale);
  Image<Bgr, Byte> srcNewSize = new Image<Bgr, byte>(size);
  CvInvoke.Resize(src, srcNewSize, size);
  //將圖像轉(zhuǎn)換為灰度
  UMat grayImage = new UMat();
  CvInvoke.CvtColor(srcNewSize, grayImage, ColorConversion.Bgr2Gray);
  //使用高斯濾波去除噪聲
  CvInvoke.GaussianBlur(grayImage, grayImage, new Size(3, 3), 3);
  UMat cannyEdges = new UMat();
  CvInvoke.Canny(grayImage, cannyEdges, 60, 180);//通過邊緣化,然后取出輪廓
   
  #region 取三角形和矩形的頂點坐標
  List<Triangle2DF> triangleList = new List<Triangle2DF>();
  List<RotatedRect> boxList = new List<RotatedRect>(); //旋轉(zhuǎn)的矩形框
​
  using (VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint())
  {
    CvInvoke.FindContours(cannyEdges, contours, null, RetrType.List, ChainApproxMethod.ChainApproxSimple);
    int count = contours.Size;
    for (int i = 0; i < count; i++)
    {
      using (VectorOfPoint contour = contours[i])
      using (VectorOfPoint approxContour = new VectorOfPoint())
      {
        CvInvoke.ApproxPolyDP(contour, approxContour, CvInvoke.ArcLength(contour, true) * 0.08, true);
        //僅考慮面積大于50的輪廓
        if (CvInvoke.ContourArea(approxContour, false) > 50)
        {
          if (approxContour.Size == 3) //輪廓有3個頂點:三角形
          {
            System.Drawing.Point[] pts = approxContour.ToArray();
            triangleList.Add(new Triangle2DF(pts[0], pts[1], pts[2]));
          }
          else if (approxContour.Size == 4) //輪廓有4個頂點
          {
            #region 檢測角度,如果角度都在 [80, 100] 之間,則為矩形
            bool isRectangle = true;
            System.Drawing.Point[] pts = approxContour.ToArray();
            LineSegment2D[] edges = Emgu.CV.PointCollection.PolyLine(pts, true);
​
            for (int j = 0; j < edges.Length; j++)
            {
              double angle = Math.Abs(edges[(j + 1) % edges.Length].GetExteriorAngleDegree(edges[j]));
              if (angle < 80 || angle > 100)
              {
                isRectangle = false;
                break;
              }
            }
            #endregion
            if (isRectangle) boxList.Add(CvInvoke.MinAreaRect(approxContour));
          }
        }
      }
    }
  }
  #endregion
     
  #region 保存剪切的最大的矩形圖片 
  Rectangle rectangle = new Rectangle(0, 0, src.Width, src.Height);
  int maxWidth = 0;
  //boxList = boxList.Where(p => p.Size.Width > 300).ToList();
  for (int i = 0; i < boxList.Count(); i++)
  {
    RotatedRect box = boxList[i];
    Rectangle rectangleTemp = box.MinAreaRect();
    //這里對取到的頂點坐標進行了加寬,因為矩形可能存在角度,這里沒有進行角度旋轉(zhuǎn),所以加寬了取值范圍就可以取到完整的圖了
    rectangleTemp = new Rectangle(rectangleTemp.X * scale, rectangleTemp.Y * scale, rectangleTemp.Width * scale + scale, rectangleTemp.Height * scale + scale);
    
    //取最大的矩形圖片
    if (rectangleTemp.Width > maxWidth)
    {
      maxWidth = rectangleTemp.Width;
      rectangle = rectangleTemp;
    }
  }
  src.Draw(rectangle, new Bgr(System.Drawing.Color.Red), 4);//在圖片中畫線
  CvInvoke.Imwrite("原始圖片.bmp", src); //保存原始圖片
  CvInvoke.cvSetImageROI(src.Ptr, rectangle);//設(shè)置興趣點—ROI(region of interest )
  var clone = src.Clone();
  CvInvoke.Imwrite("剪切的矩形圖片.bmp", clone); //保存結(jié)果圖 
  #endregion
  src.Dispose();
  srcNewSize.Dispose();
  grayImage.Dispose();
}

然后編寫一個打開文件的函數(shù),在成功打開文件后調(diào)用CutRectangleImage。

private void btnRectangle_Click(object sender, RoutedEventArgs e)
{
  System.Windows.Forms.OpenFileDialog frm = new System.Windows.Forms.OpenFileDialog();
  frm.Filter = "(*.jpg,*.png,*.jpeg,*.bmp,*.gif)|*.jgp;*.png;*.jpeg;*.bmp;*.gif|All files(*.*)|*.*";
  if (frm.ShowDialog() == System.Windows.Forms.DialogResult.OK)
  {
    CutRectangleImage(frm.FileName);
  }
}

然后運行項目,點擊剪切矩形文件。

然后到debug文件夾下,查看結(jié)果。

測試結(jié)果如下圖所示:

圖中紅線為檢測到矩形后,手動畫上去的矩形輪廓。

使用OPenCV剪切圓形

編寫矩形剪切函數(shù)——CutCircleImage。

函數(shù)里,我們依然先將圖像進行縮放,為了有效的減少檢測到的圓形數(shù)量。

再將圖片處理成灰度模式,然后再高斯模糊。

然后再使用霍夫圓檢測函數(shù),獲取圓的圓心和半徑。

最后再根據(jù)圓心和半徑計算出最小矩形,然后將圓剪切并保存。

代碼如下:

public void CutCircleImage(string imagePath)
{
  Image<Bgr, Byte> src = new Image<Bgr, byte>(imagePath);
  
  int scale = 1;
  if (src.Width > 500)
  {
    scale = 2;
  }
  if (src.Width > 1000)
  {
    scale = 10;
  }
  if (src.Width > 10000)
  {
    scale = 100;
  }
  var size = new Size(src.Width / scale, src.Height / scale);
  Image<Bgr, Byte> srcNewSize = new Image<Bgr, byte>(size);
  CvInvoke.Resize(src, srcNewSize, size);
  //將圖像轉(zhuǎn)換為灰度
  UMat grayImage = new UMat();
  CvInvoke.CvtColor(srcNewSize, grayImage, ColorConversion.Bgr2Gray);
  //使用高斯濾波去除噪聲
  CvInvoke.GaussianBlur(grayImage, grayImage, new Size(3, 3), 3);
  //霍夫圓檢測
  CircleF[] circles = CvInvoke.HoughCircles(grayImage, HoughModes.Gradient, 2.0, 200.0, 100.0, 180.0, 5);
  
  Rectangle rectangle = new Rectangle();
  float maxRadius = 0;
  foreach (CircleF circle in circles)
  {
    var center = circle.Center;//圓心
    var radius = circle.Radius;//半徑
    if (radius > maxRadius)
    {
      maxRadius = radius;
      rectangle = new Rectangle((int)(center.X - radius) * scale,
        (int)(center.Y - radius) * scale,
        (int)radius * 2 * scale + scale,
        (int)radius * 2 * scale + scale);
    }
    srcNewSize.Draw(circle, new Bgr(System.Drawing.Color.Blue), 4);
​
  }
  CvInvoke.Imwrite("原始圖片.bmp", srcNewSize); //保存原始圖片
  if (maxRadius == 0)
  {
    MessageBox.Show("沒有圓形");
  }
  CvInvoke.cvSetImageROI(srcNewSize.Ptr, rectangle);//設(shè)置興趣點—ROI(region of interest )
  var clone = srcNewSize.Clone();
  CvInvoke.Imwrite("剪切的圓形圖片.bmp", clone); //保存結(jié)果圖 
  src.Dispose();
  srcNewSize.Dispose();
  grayImage.Dispose();
}

運行項目進行測試,結(jié)果如下:

----------------------------------------------------------------------------------------------------

到此,C#使用OpenCV剪切圖像中的圓形和矩形就已經(jīng)介紹完了。

代碼已經(jīng)傳到Github上了,歡迎大家下載。

Github地址:https://github.com/kiba518/OpenCv_CutImage

到此這篇關(guān)于C#使用OpenCV剪切圖像中的圓形和矩形的文章就介紹到這了,更多相關(guān)C#剪切圖像中的圓形和矩形內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • WPF+DiffPlex實現(xiàn)文本比對工具

    WPF+DiffPlex實現(xiàn)文本比對工具

    現(xiàn)行的文本編輯器大多都具備文本查詢的能力,但是并不能直觀的告訴用戶兩段文字的細微差異,所以對比工具在某種情況下,就起到了很便捷的效率。本文將利用DiffPlex實現(xiàn)簡易的文本比對工具,需要的可以參考一下
    2022-11-11
  • C# System.Linq 萬能的查詢語句示例詳解

    C# System.Linq 萬能的查詢語句示例詳解

    在C#編程中,System.Linq命名空間提供了一組豐富的查詢功能,使得操作各種數(shù)據(jù)類型更加高效和便捷,本文介紹了如何使用Linq提供的不同查詢子句和方法,以及這些方法的具體應(yīng)用示例,旨在幫助開發(fā)者更好地掌握Linq的查詢技巧,感興趣的朋友一起看看吧
    2024-09-09
  • C#多線程等待所有子線程結(jié)束的示例

    C#多線程等待所有子線程結(jié)束的示例

    這篇文章主要介紹了C#多線程等待所有子線程結(jié)束的示例,幫助大家更好的理解和學習c#編程語言,感興趣的朋友可以了解下
    2020-12-12
  • C# 利用VS編寫一個簡單的網(wǎng)游客戶端

    C# 利用VS編寫一個簡單的網(wǎng)游客戶端

    本文主要介紹了在visual studio中利用C#編寫一個簡單的網(wǎng)游客戶端,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • C# DataTable使用方法詳解

    C# DataTable使用方法詳解

    這篇文章主要為大家詳細介紹了C# DataTable的使用方法,感興趣的小伙伴們可以參考一下
    2016-02-02
  • C#中Web.Config加密與解密的方法

    C#中Web.Config加密與解密的方法

    C#中Web.Config加密與解密的方法,需要的朋友可以參考一下
    2013-04-04
  • C# 設(shè)計模式系列教程-裝飾模式

    C# 設(shè)計模式系列教程-裝飾模式

    每個裝飾對象只關(guān)心自己的功能,不需要關(guān)心如何被添加到對象鏈當中。它是由Decorator的SetComponent方法來實現(xiàn)的,因而它們的職責是單一的。
    2016-06-06
  • C#操作注冊表的方法

    C#操作注冊表的方法

    以下從‘讀’‘寫’‘刪除’‘判斷’四個事例實現(xiàn)對注冊表的簡單操作
    2007-03-03
  • C#(.net)中按字節(jié)數(shù)截取字符串最后出現(xiàn)亂碼問題的解決

    C#(.net)中按字節(jié)數(shù)截取字符串最后出現(xiàn)亂碼問題的解決

    這篇文章主要給大家介紹了關(guān)于C#(.net)中按字節(jié)數(shù)截取字符串最后出現(xiàn)亂碼問題的解決方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2018-06-06
  • C# 利用AForge實現(xiàn)攝像頭信息采集

    C# 利用AForge實現(xiàn)攝像頭信息采集

    這篇文章主要介紹了C# 如何利用AForge實現(xiàn)攝像頭信息采集,文中示例代碼非常詳細,幫助大家更好的理解和學習,感興趣的朋友可以了解下
    2020-07-07

最新評論

平舆县| 福建省| 富裕县| 自贡市| 嘉峪关市| 贡嘎县| 修水县| 龙山县| 长岭县| 紫金县| 汾阳市| 芦山县| 乐亭县| 静安区| 翼城县| 恩施市| 和平县| 常山县| 息烽县| 凤凰县| 乌海市| 丹阳市| 宁陕县| 扎赉特旗| 临漳县| 金平| 唐河县| 江永县| 吉安市| 苏州市| 班戈县| 四子王旗| 柘城县| 阳原县| 马边| 郎溪县| 大冶市| 张家川| 罗平县| 清徐县| 新邵县|