C#利用OpenCvSharp實(shí)現(xiàn)玉米粒計(jì)數(shù)
效果

項(xiàng)目

代碼
using OpenCvSharp;
using System;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace OpenCvSharp_Demo
{
public partial class frmMain : Form
{
public frmMain()
{
InitializeComponent();
}
string fileFilter = "*.*|*.bmp;*.jpg;*.jpeg;*.tiff;*.tiff;*.png";
string image_path = "";
DateTime dt1 = DateTime.Now;
DateTime dt2 = DateTime.Now;
Mat image;
Mat result_image;
StringBuilder sb = new StringBuilder();
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = fileFilter;
if (ofd.ShowDialog() != DialogResult.OK) return;
pictureBox1.Image = null;
pictureBox2.Image = null;
textBox1.Text = "";
image_path = ofd.FileName;
pictureBox1.Image = new Bitmap(image_path);
image = new Mat(image_path);
}
private void Form1_Load(object sender, EventArgs e)
{
//test
image_path = "test_img/1.jpg";
image = new Mat(image_path);
pictureBox1.Image = new Bitmap(image_path);
}
private void button2_Click(object sender, EventArgs e)
{
if (image_path == "")
{
return;
}
textBox1.Text = "檢測(cè)中,請(qǐng)稍等……";
pictureBox2.Image = null;
Application.DoEvents();
result_image = image.Clone();
//二值化操作
Mat grayimg = new Mat();
Cv2.CvtColor(image, grayimg, ColorConversionCodes.BGR2GRAY);
Mat BinaryImg = new Mat();
Cv2.Threshold(grayimg, BinaryImg, 240, 255, ThresholdTypes.Binary);
//Cv2.ImShow("二值化", BinaryImg);
//腐蝕
Mat kernel = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(15, 15));
Mat morhImage = new Mat();
Cv2.Dilate(BinaryImg, morhImage, kernel, null, 2);
//Cv2.ImShow("morphology", morhImage);
//距離變換:用于二值化圖像中的每一個(gè)非零點(diǎn)距自己最近的零點(diǎn)的距離,距離變換圖像上越亮的點(diǎn),代表了這一點(diǎn)距離零點(diǎn)的距離越遠(yuǎn)
Mat dist = new Mat();
Cv2.BitwiseNot(morhImage, morhImage);
/*
OpenCV中,函數(shù)distanceTransform()用于計(jì)算圖像中每一個(gè)非零點(diǎn)像素與其最近的零點(diǎn)像素之間的距離,
輸出的是保存每一個(gè)非零點(diǎn)與最近零點(diǎn)的距離信息,圖像上越亮的點(diǎn),代表了離零點(diǎn)的距離越遠(yuǎn)。
用途:
可以根據(jù)距離變換的這個(gè)性質(zhì),經(jīng)過(guò)簡(jiǎn)單的運(yùn)算,用于細(xì)化字符的輪廓和查找物體質(zhì)心(中心)。
*/
/*
距離變換的處理圖像通常都是二值圖像,而二值圖像其實(shí)就是把圖像分為兩部分,即背景和物體兩部分,物體通常又稱(chēng)為前景目標(biāo)。
通常我們把前景目標(biāo)的灰度值設(shè)為255(即白色),背景的灰度值設(shè)為0(即黑色)。
所以定義中的非零像素點(diǎn)即為前景目標(biāo),零像素點(diǎn)即為背景。
所以圖像中前景目標(biāo)中的像素點(diǎn)距離背景越遠(yuǎn),那么距離就越大,如果我們用這個(gè)距離值替換像素值,那么新生成的圖像中這個(gè)點(diǎn)越亮。
*/
//User:用戶自定義
//L1: 曼哈頓距離
//L2: 歐式距離
//C: 棋盤(pán)距離
Cv2.DistanceTransform(morhImage, dist, DistanceTypes.L1, DistanceTransformMasks.Mask3);
Cv2.Normalize(dist, dist, 0, 1.0, NormTypes.MinMax); //范圍在0~1之間
//Cv2.ImShow("distance", dist);
//形態(tài)學(xué)處理
Mat MorphImg = new Mat();
dist.ConvertTo(MorphImg, MatType.CV_8U);
Cv2.Threshold(MorphImg, MorphImg, 0.99, 255, ThresholdTypes.Binary); //上圖像素值在0~1之間
kernel = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(7, 3), new OpenCvSharp.Point(-1, -1));
Cv2.MorphologyEx(MorphImg, MorphImg, MorphTypes.Open, kernel); //開(kāi)操作
//Cv2.ImShow("t-distance", MorphImg);
//找到種子的輪廓區(qū)域
OpenCvSharp.Point[][] contours;
HierarchyIndex[] hierarchly;
Cv2.FindContours(MorphImg, out contours, out hierarchly, RetrievalModes.External, ContourApproximationModes.ApproxSimple, new OpenCvSharp.Point(0, 0));
Mat markers = Mat.Zeros(image.Size(), MatType.CV_8UC3);
int x, y, w, h;
Rect rect;
for (int i = 0; i < contours.Length; i++)
{
// Cv2.DrawContours(markers, contours, i, Scalar.RandomColor(), 2, LineTypes.Link8, hierarchly);
rect = Cv2.BoundingRect(contours[i]);
x = rect.X;
y = rect.Y;
w = rect.Width;
h = rect.Height;
Cv2.Circle(result_image, x + w / 2, y + h / 2, 20, new Scalar(0, 0, 255), -1);
if (i >= 9)
{
Cv2.PutText(result_image, (i + 1).ToString(), new OpenCvSharp.Point(x + w / 2 - 18, y + h / 2 + 8), HersheyFonts.HersheySimplex, 0.8, new Scalar(0, 255, 0), 2);
}
else
{
Cv2.PutText(result_image, (i + 1).ToString(), new OpenCvSharp.Point(x + w / 2 - 8, y + h / 2 + 8), HersheyFonts.HersheySimplex, 0.8, new Scalar(0, 255, 0), 2);
}
}
textBox1.Text = "number of corns: " + contours.Length;
pictureBox2.Image = new Bitmap(result_image.ToMemoryStream());
}
private void pictureBox2_DoubleClick(object sender, EventArgs e)
{
Common.ShowNormalImg(pictureBox2.Image);
}
private void pictureBox1_DoubleClick(object sender, EventArgs e)
{
Common.ShowNormalImg(pictureBox1.Image);
}
}
}到此這篇關(guān)于C#利用OpenCvSharp實(shí)現(xiàn)玉米粒計(jì)數(shù)的文章就介紹到這了,更多相關(guān)C# OpenCvSharp計(jì)數(shù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
c#重寫(xiě)TabControl控件實(shí)現(xiàn)關(guān)閉按鈕的方法
這是關(guān)于c#重寫(xiě)TabControl控件實(shí)現(xiàn)關(guān)閉按鈕的例子,整理了一下,與大家分享。2013-04-04
C#調(diào)用OpenCV開(kāi)發(fā)簡(jiǎn)易版美圖工具【推薦】
本文主要介紹在WPF項(xiàng)目中使用OpenCVSharp3-AnyCPU開(kāi)源類(lèi)庫(kù)處理圖片,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2019-10-10
unity實(shí)現(xiàn)場(chǎng)景跳轉(zhuǎn)
這篇文章主要為大家詳細(xì)介紹了unity實(shí)現(xiàn)場(chǎng)景跳轉(zhuǎn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-04-04
C# HTTP認(rèn)證方式詳解與代碼實(shí)現(xiàn)
在C#中,HTTP認(rèn)證是客戶端與服務(wù)器之間進(jìn)行身份驗(yàn)證的一種機(jī)制,常見(jiàn)的HTTP認(rèn)證方式包括:Basic認(rèn)證、Digest認(rèn)證、OAuth、Bearer Token等,下面我們將從工作原理、優(yōu)缺點(diǎn)對(duì)比、代碼實(shí)現(xiàn)、案例實(shí)戰(zhàn)四個(gè)方面詳細(xì)介紹這些認(rèn)證方式,需要的朋友可以參考下2025-03-03
詳解WPF如何動(dòng)態(tài)生成DataGrid的行和列
在日常開(kāi)發(fā)中,DataGrid作為二維表格,非常適合數(shù)據(jù)的展示和統(tǒng)計(jì),本文以一些簡(jiǎn)單的小例子,簡(jiǎn)述在WPF開(kāi)發(fā)中,如何動(dòng)態(tài)生成DataGrid的行和列,需要的可以了解下2024-02-02

