c#聯合halcon的基礎教程(案例:亮度計算、角度計算和缺陷檢測)(含halcon代碼)

目錄

1.環境配置

2.案例一:亮度計算

halcon代碼:

主界面代碼:

3.案例二: 角度計算

halcon代碼:

主界面代碼:

4.案例三:缺陷檢測

halcon代碼:

主界面代碼:


通過網盤分享的文件:halcon-25.05.0.0-x64-win64
鏈接:?百度網盤 請輸入提取碼

提取碼: whek

1.環境配置

A.創建新c# winform 項目,點擊添加引用。

(halcon安裝目錄"D:\halcon\HALCON-25.05-Progress\bin\dotnet35\halcondotnet.dll")

B.把halcondotnet.dll拖到工具箱。

C.把"D:\halcon\HALCON-25.05-Progress\bin\x64-win64\halcon.dll"復制到項目的Debug文件夾中

D.項目屬性生成中:取消勾選 首選32

2.案例一:亮度計算

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 如圖,計算 選框區域的亮度。

c#上添加幾個控件

添加openfiledialog控件

點擊選擇文件后把地址放在textbox1

? ? ? ? private void button2_Click(object sender, EventArgs e)
? ? ? ? {

? ? ? ? ? ? using (OpenFileDialog openFileDialog = new OpenFileDialog())
? ? ? ? ? ? {
? ? ? ? ? ? ? ? openFileDialog.Filter = "所有文件|*.*";
? ? ? ? ? ? ? ? openFileDialog.Title = "選擇文件";

? ? ? ? ? ? ? ? if (openFileDialog.ShowDialog() == DialogResult.OK)
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? string filePath = openFileDialog.FileName;
? ? ? ? ? ? ? ? ? ? textBox1.Text = filePath;

? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }
?

打開halcon軟件,完成項目功能

halcon代碼:

read_image (Heibai, 'C:/Users/86957/Desktop/heibai.png')rgb1_to_gray(Heibai, GrayImage)
get_image_size(GrayImage, Width, Height)
dev_open_window(0, 0, Width, Height, 'white', WindowHandle)
dev_display(GrayImage)* 交互式繪制矩形(軸對齊)
draw_rectangle1(WindowHandle, Row1, Column1, Row2, Column2)
* 參數說明:
* Row1, Column1: 矩形左上角坐標
* Row2, Column2: 矩形右下角坐標* 生成矩形區域
gen_rectangle1(Rectangle, Row1, Column1, Row2, Column2)* 顯示結果
dev_set_color('red')
dev_display(Rectangle)*計算選框內的像素平均值
intensity(Rectangle, GrayImage, Mean, Deviation)
* 輸出結果:
* Mean: 平均灰度值
* Deviation: 標準差(可選)* 在窗口顯示計算結果
set_tposition(WindowHandle, 20, 20)
write_string(WindowHandle, 'Mean Intensity: ' + Mean$'.2f')

點擊文件,導出程序。

把導出的.cs文件,復制到項目中。并進行修改。

我們只需要action();并把他放入項目的命名空間;還需要增加輸入str filepath。

原來的hd.cs:

修改后的hd.cs如下:
?

//
// File generated by HDevelop for HALCON/.NET (C#) Version 25.05.0.0
// Non-ASCII strings in this file are encoded in local-8-bit encoding (cp936).
// 
// Please note that non-ASCII characters in string constants are exported
// as octal codes in order to guarantee that the strings are correctly
// created on all systems, independent on any compiler settings.
// 
// Source files with different encoding should not be mixed in one project.
//using HalconDotNet;
namespace halcon_cs
{public partial class HDevelopExport{// Main procedure public void action(string filepath){// Local iconic variables HObject ho_Heibai, ho_GrayImage, ho_Rectangle;// Local control variables HTuple hv_Width = new HTuple(), hv_Height = new HTuple();HTuple hv_WindowHandle = new HTuple(), hv_Row1 = new HTuple();HTuple hv_Column1 = new HTuple(), hv_Row2 = new HTuple();HTuple hv_Column2 = new HTuple(), hv_Mean = new HTuple();HTuple hv_Deviation = new HTuple();// Initialize local and output iconic variables HOperatorSet.GenEmptyObj(out ho_Heibai);HOperatorSet.GenEmptyObj(out ho_GrayImage);HOperatorSet.GenEmptyObj(out ho_Rectangle);ho_Heibai.Dispose();HOperatorSet.ReadImage(out ho_Heibai, filepath);ho_GrayImage.Dispose();HOperatorSet.Rgb1ToGray(ho_Heibai, out ho_GrayImage);hv_Width.Dispose(); hv_Height.Dispose();HOperatorSet.GetImageSize(ho_GrayImage, out hv_Width, out hv_Height);HOperatorSet.SetWindowAttr("background_color", "white");HOperatorSet.OpenWindow(0, 0, hv_Width, hv_Height, 0, "visible", "", out hv_WindowHandle);HDevWindowStack.Push(hv_WindowHandle);if (HDevWindowStack.IsOpen()){HOperatorSet.DispObj(ho_GrayImage, HDevWindowStack.GetActive());}//交互式繪制矩形(軸對齊)hv_Row1.Dispose(); hv_Column1.Dispose(); hv_Row2.Dispose(); hv_Column2.Dispose();HOperatorSet.DrawRectangle1(hv_WindowHandle, out hv_Row1, out hv_Column1, out hv_Row2,out hv_Column2);//參數說明://Row1, Column1: 矩形左上角坐標//Row2, Column2: 矩形右下角坐標//生成矩形區域ho_Rectangle.Dispose();HOperatorSet.GenRectangle1(out ho_Rectangle, hv_Row1, hv_Column1, hv_Row2, hv_Column2);//顯示結果if (HDevWindowStack.IsOpen()){HOperatorSet.SetColor(HDevWindowStack.GetActive(), "red");}if (HDevWindowStack.IsOpen()){HOperatorSet.DispObj(ho_Rectangle, HDevWindowStack.GetActive());}//計算選框內的像素平均值hv_Mean.Dispose(); hv_Deviation.Dispose();HOperatorSet.Intensity(ho_Rectangle, ho_GrayImage, out hv_Mean, out hv_Deviation);//輸出結果://Mean: 平均灰度值//Deviation: 標準差(可選)//在窗口顯示計算結果HOperatorSet.SetTposition(hv_WindowHandle, 20, 20);using (HDevDisposeHelper dh = new HDevDisposeHelper()){HOperatorSet.WriteString(hv_WindowHandle, "Mean Intensity: " + (hv_Mean.TupleString(".2f")));}ho_Heibai.Dispose();ho_GrayImage.Dispose();ho_Rectangle.Dispose();hv_Width.Dispose();hv_Height.Dispose();hv_WindowHandle.Dispose();hv_Row1.Dispose();hv_Column1.Dispose();hv_Row2.Dispose();hv_Column2.Dispose();hv_Mean.Dispose();hv_Deviation.Dispose();}}
}

主界面代碼:

如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using HalconDotNet;
namespace halcon_cs
{public partial class Form1 : Form{public Form1(){InitializeComponent();}private void button1_Click(object sender, EventArgs e){string filepath = textBox1.Text;HDevelopExport hd = new HDevelopExport();hd.action(filepath);}private void button2_Click(object sender, EventArgs e){using (OpenFileDialog openFileDialog = new OpenFileDialog()){openFileDialog.Filter = "所有文件|*.*";openFileDialog.Title = "選擇文件";if (openFileDialog.ShowDialog() == DialogResult.OK){string filePath = openFileDialog.FileName;textBox1.Text = filePath;}}}}
}

設計器代碼如下:

using HalconDotNet;namespace halcon_cs
{partial class Form1{/// <summary>/// 必需的設計器變量。/// </summary>private System.ComponentModel.IContainer components = null;/// <summary>/// 清理所有正在使用的資源。/// </summary>/// <param name="disposing">如果應釋放托管資源,為 true;否則為 false。</param>protected override void Dispose(bool disposing){if (disposing && (components != null)){components.Dispose();}base.Dispose(disposing);}#region Windows 窗體設計器生成的代碼/// <summary>/// 設計器支持所需的方法 - 不要修改/// 使用代碼編輯器修改此方法的內容。/// </summary>private void InitializeComponent(){this.button1 = new System.Windows.Forms.Button();this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog();this.button2 = new System.Windows.Forms.Button();this.textBox1 = new System.Windows.Forms.TextBox();this.SuspendLayout();// // button1// this.button1.Location = new System.Drawing.Point(374, 594);this.button1.Name = "button1";this.button1.Size = new System.Drawing.Size(430, 101);this.button1.TabIndex = 1;this.button1.Text = "start";this.button1.UseVisualStyleBackColor = true;this.button1.Click += new System.EventHandler(this.button1_Click);// // openFileDialog1// this.openFileDialog1.FileName = "openFileDialog1";// // button2// this.button2.Location = new System.Drawing.Point(779, 41);this.button2.Name = "button2";this.button2.Size = new System.Drawing.Size(116, 43);this.button2.TabIndex = 4;this.button2.Text = "選擇文件";this.button2.UseVisualStyleBackColor = true;this.button2.Click += new System.EventHandler(this.button2_Click);// // textBox1// this.textBox1.Location = new System.Drawing.Point(314, 50);this.textBox1.Name = "textBox1";this.textBox1.Size = new System.Drawing.Size(459, 28);this.textBox1.TabIndex = 5;// // Form1// this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 18F);this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;this.ClientSize = new System.Drawing.Size(1176, 821);this.Controls.Add(this.textBox1);this.Controls.Add(this.button2);this.Controls.Add(this.button1);this.Name = "Form1";this.Text = "Form1";this.ResumeLayout(false);this.PerformLayout();}#endregionprivate System.Windows.Forms.Button button1;private System.Windows.Forms.OpenFileDialog openFileDialog1;private System.Windows.Forms.Button button2;private System.Windows.Forms.TextBox textBox1;}
}

運行后;

運行后,彈窗無法關閉,后續添加halcon控件來顯示圖像。

3.案例二: 角度計算

如圖,計算三角形 三個角的角度。

在案例一的基礎上,增加HWindowcontrol

顯示圖像按鈕:
?

        private void button1_Click(object sender, EventArgs e){//讀取文件HOperatorSet.ReadImage(out TestImage, textBox1.Text);//獲取圖片大小HTuple Width, Height;HOperatorSet.GetImageSize(TestImage, out Width, out Height);//設置圖片顯示范圍 hWindowControl1.HalconWindow獲得窗體句柄HOperatorSet.SetPart(hWindowControl1.HalconWindow, 0, 0, (Height - 1), (Width - 1)); //0,0, (Height - 1), (Width - 1)代表從0,0坐標到圖片的寬高坐標,達到全屏顯示//將圖片投射到窗體上HOperatorSet.DispObj(TestImage, hWindowControl1.HalconWindow);//將TestImage變量投射到句柄窗口上}

計算角度按鈕:

        private void button3_Click(object sender, EventArgs e){double[] result;HDevelopExport hDevelopExport = new HDevelopExport();result = hDevelopExport.action(textBox1.Text);foreach (double indexer in result) { textBox2.AppendText(indexer.ToString()+"\r\n");}}

使用halcon代碼轉換成的action,計算角度。

主要方法為:

A獲取區域輪廓

B將輪廓分割為線段

C得到線段的終點和起點

D計算線段交點

E根據三角形三個頂點,計算三個內角

運行后:

halcon代碼:

read_image (Image, 'C:/Users/86957/Desktop/sanjiao.png')
rgb1_to_gray (Image, GrayImage)
threshold(GrayImage, TriangleRegion, 0, 128)
gen_contour_region_xld(TriangleRegion, Contour, 'border')
segment_contours_xld(Contour, Segments, 'lines_circles', 5, 4, 2)count_obj(Segments, NumSegments)
Angles := []for i := 1 to 3 by 1select_obj(Segments, Segment, i)fit_line_contour_xld(Segment, 'tukey', -1, 0, 5, 2, RowBegin, ColBegin, RowEnd, ColEnd, _, _, _)* 存儲線段端點if (i == 1)Line1 := [RowBegin, ColBegin, RowEnd, ColEnd]elseif (i == 2)Line2 := [RowBegin, ColBegin, RowEnd, ColEnd]elseLine3 := [RowBegin, ColBegin, RowEnd, ColEnd]endifendforintersection_lines(Line1[0], Line1[1], Line1[2], Line1[3], Line2[0], Line2[1], Line2[2], Line2[3], RowV1, ColV1, IsOverlapping1)
intersection_lines(Line2[0], Line2[1], Line2[2], Line2[3], Line3[0], Line3[1], Line3[2], Line3[3], RowV2, ColV2, IsOverlapping2)
intersection_lines(Line3[0], Line3[1], Line3[2], Line3[3], Line1[0], Line1[1], Line1[2], Line1[3], RowV3, ColV3, IsOverlapping3) * 1. 計算三條邊的長度
distance_pp(RowV1, ColV1, RowV2, ColV2, AB)
distance_pp(RowV1, ColV1, RowV3, ColV3, AC) 
distance_pp(RowV2, ColV2, RowV3, ColV3, BC)* 2. 使用余弦定理計算角度
* 頂點A的角度 (對邊BC)
cosAngleA := (AC*AC + AB*AB - BC*BC) / (2 * AC * AB)
AngleA := acos(cosAngleA) * 180 / 3.1415926535* 頂點B的角度 (對邊AC)
cosAngleB := (AB*AB + BC*BC - AC*AC) / (2 * AB * BC)
AngleB := acos(cosAngleB) * 180 / 3.1415926535* 頂點C的角度 (對邊AB)
cosAngleC := (AC*AC + BC*BC - AB*AB) / (2 * AC * BC)
AngleC := acos(cosAngleC) * 180 / 3.1415926535

轉成c#程序,并修改 輸入輸出。

//
// File generated by HDevelop for HALCON/.NET (C#) Version 25.05.0.0
// Non-ASCII strings in this file are encoded in local-8-bit encoding (cp936).
// 
// Please note that non-ASCII characters in string constants are exported
// as octal codes in order to guarantee that the strings are correctly
// created on all systems, independent on any compiler settings.
// 
// Source files with different encoding should not be mixed in one project.
//using HalconDotNet;
namespace halcon_cs
{public partial class HDevelopExport{public double[] action(string imgpath ){// Local iconic variables HObject ho_Image, ho_GrayImage, ho_TriangleRegion;HObject ho_Contour, ho_Segments, ho_Segment = null;// Local control variables HTuple hv_NumSegments = new HTuple(), hv_Angles = new HTuple();HTuple hv_i = new HTuple(), hv_RowBegin = new HTuple();HTuple hv_ColBegin = new HTuple(), hv_RowEnd = new HTuple();HTuple hv_ColEnd = new HTuple(), hv__ = new HTuple(), hv_Line1 = new HTuple();HTuple hv_Line2 = new HTuple(), hv_Line3 = new HTuple();HTuple hv_RowV1 = new HTuple(), hv_ColV1 = new HTuple();HTuple hv_IsOverlapping1 = new HTuple(), hv_RowV2 = new HTuple();HTuple hv_ColV2 = new HTuple(), hv_IsOverlapping2 = new HTuple();HTuple hv_RowV3 = new HTuple(), hv_ColV3 = new HTuple();HTuple hv_IsOverlapping3 = new HTuple(), hv_AB = new HTuple();HTuple hv_AC = new HTuple(), hv_BC = new HTuple(), hv_cosAngleA = new HTuple();HTuple hv_AngleA = new HTuple(), hv_cosAngleB = new HTuple();HTuple hv_AngleB = new HTuple(), hv_cosAngleC = new HTuple();HTuple hv_AngleC = new HTuple(), hv___Tmp_Ctrl_0_5 = new HTuple();HTuple hv___Tmp_Ctrl_0_6 = new HTuple();// Initialize local and output iconic variables HOperatorSet.GenEmptyObj(out ho_Image);HOperatorSet.GenEmptyObj(out ho_GrayImage);HOperatorSet.GenEmptyObj(out ho_TriangleRegion);HOperatorSet.GenEmptyObj(out ho_Contour);HOperatorSet.GenEmptyObj(out ho_Segments);HOperatorSet.GenEmptyObj(out ho_Segment);ho_Image.Dispose();HOperatorSet.ReadImage(out ho_Image, imgpath);ho_GrayImage.Dispose();HOperatorSet.Rgb1ToGray(ho_Image, out ho_GrayImage);ho_TriangleRegion.Dispose();HOperatorSet.Threshold(ho_GrayImage, out ho_TriangleRegion, 0, 128);ho_Contour.Dispose();HOperatorSet.GenContourRegionXld(ho_TriangleRegion, out ho_Contour, "border");ho_Segments.Dispose();HOperatorSet.SegmentContoursXld(ho_Contour, out ho_Segments, "lines_circles",5, 4, 2);hv_NumSegments.Dispose();HOperatorSet.CountObj(ho_Segments, out hv_NumSegments);hv_Angles.Dispose();hv_Angles = new HTuple();for (hv_i = 1; (int)hv_i <= 3; hv_i = (int)hv_i + 1){ho_Segment.Dispose();HOperatorSet.SelectObj(ho_Segments, out ho_Segment, hv_i);hv_RowBegin.Dispose(); hv_ColBegin.Dispose(); hv_RowEnd.Dispose(); hv_ColEnd.Dispose(); hv__.Dispose(); hv___Tmp_Ctrl_0_5.Dispose(); hv___Tmp_Ctrl_0_6.Dispose();HOperatorSet.FitLineContourXld(ho_Segment, "tukey", -1, 0, 5, 2, out hv_RowBegin,out hv_ColBegin, out hv_RowEnd, out hv_ColEnd, out hv__, out hv___Tmp_Ctrl_0_5,out hv___Tmp_Ctrl_0_6);//存儲線段端點if ((int)(new HTuple(hv_i.TupleEqual(1))) != 0){hv_Line1.Dispose();using (HDevDisposeHelper dh = new HDevDisposeHelper()){hv_Line1 = new HTuple();hv_Line1 = hv_Line1.TupleConcat(hv_RowBegin, hv_ColBegin, hv_RowEnd, hv_ColEnd);}}else if ((int)(new HTuple(hv_i.TupleEqual(2))) != 0){hv_Line2.Dispose();using (HDevDisposeHelper dh = new HDevDisposeHelper()){hv_Line2 = new HTuple();hv_Line2 = hv_Line2.TupleConcat(hv_RowBegin, hv_ColBegin, hv_RowEnd, hv_ColEnd);}}else{hv_Line3.Dispose();using (HDevDisposeHelper dh = new HDevDisposeHelper()){hv_Line3 = new HTuple();hv_Line3 = hv_Line3.TupleConcat(hv_RowBegin, hv_ColBegin, hv_RowEnd, hv_ColEnd);}}}using (HDevDisposeHelper dh = new HDevDisposeHelper()){hv_RowV1.Dispose(); hv_ColV1.Dispose(); hv_IsOverlapping1.Dispose();HOperatorSet.IntersectionLines(hv_Line1.TupleSelect(0), hv_Line1.TupleSelect(1), hv_Line1.TupleSelect(2), hv_Line1.TupleSelect(3), hv_Line2.TupleSelect(0), hv_Line2.TupleSelect(1), hv_Line2.TupleSelect(2), hv_Line2.TupleSelect(3), out hv_RowV1, out hv_ColV1, out hv_IsOverlapping1);}using (HDevDisposeHelper dh = new HDevDisposeHelper()){hv_RowV2.Dispose(); hv_ColV2.Dispose(); hv_IsOverlapping2.Dispose();HOperatorSet.IntersectionLines(hv_Line2.TupleSelect(0), hv_Line2.TupleSelect(1), hv_Line2.TupleSelect(2), hv_Line2.TupleSelect(3), hv_Line3.TupleSelect(0), hv_Line3.TupleSelect(1), hv_Line3.TupleSelect(2), hv_Line3.TupleSelect(3), out hv_RowV2, out hv_ColV2, out hv_IsOverlapping2);}using (HDevDisposeHelper dh = new HDevDisposeHelper()){hv_RowV3.Dispose(); hv_ColV3.Dispose(); hv_IsOverlapping3.Dispose();HOperatorSet.IntersectionLines(hv_Line3.TupleSelect(0), hv_Line3.TupleSelect(1), hv_Line3.TupleSelect(2), hv_Line3.TupleSelect(3), hv_Line1.TupleSelect(0), hv_Line1.TupleSelect(1), hv_Line1.TupleSelect(2), hv_Line1.TupleSelect(3), out hv_RowV3, out hv_ColV3, out hv_IsOverlapping3);}//1. 計算三條邊的長度hv_AB.Dispose();HOperatorSet.DistancePp(hv_RowV1, hv_ColV1, hv_RowV2, hv_ColV2, out hv_AB);hv_AC.Dispose();HOperatorSet.DistancePp(hv_RowV1, hv_ColV1, hv_RowV3, hv_ColV3, out hv_AC);hv_BC.Dispose();HOperatorSet.DistancePp(hv_RowV2, hv_ColV2, hv_RowV3, hv_ColV3, out hv_BC);//2. 使用余弦定理計算角度//頂點A的角度 (對邊BC)hv_cosAngleA.Dispose();using (HDevDisposeHelper dh = new HDevDisposeHelper()){hv_cosAngleA = (((hv_AC * hv_AC) + (hv_AB * hv_AB)) - (hv_BC * hv_BC)) / ((2 * hv_AC) * hv_AB);}hv_AngleA.Dispose();using (HDevDisposeHelper dh = new HDevDisposeHelper()){hv_AngleA = ((hv_cosAngleA.TupleAcos()) * 180) / 3.1415926535;}//頂點B的角度 (對邊AC)hv_cosAngleB.Dispose();using (HDevDisposeHelper dh = new HDevDisposeHelper()){hv_cosAngleB = (((hv_AB * hv_AB) + (hv_BC * hv_BC)) - (hv_AC * hv_AC)) / ((2 * hv_AB) * hv_BC);}hv_AngleB.Dispose();using (HDevDisposeHelper dh = new HDevDisposeHelper()){hv_AngleB = ((hv_cosAngleB.TupleAcos()) * 180) / 3.1415926535;}//頂點C的角度 (對邊AB)hv_cosAngleC.Dispose();using (HDevDisposeHelper dh = new HDevDisposeHelper()){hv_cosAngleC = (((hv_AC * hv_AC) + (hv_BC * hv_BC)) - (hv_AB * hv_AB)) / ((2 * hv_AC) * hv_BC);}hv_AngleC.Dispose();using (HDevDisposeHelper dh = new HDevDisposeHelper()){hv_AngleC = ((hv_cosAngleC.TupleAcos()) * 180) / 3.1415926535;}ho_Image.Dispose();ho_GrayImage.Dispose();ho_TriangleRegion.Dispose();ho_Contour.Dispose();ho_Segments.Dispose();ho_Segment.Dispose();hv_NumSegments.Dispose();hv_Angles.Dispose();hv_i.Dispose();hv_RowBegin.Dispose();hv_ColBegin.Dispose();hv_RowEnd.Dispose();hv_ColEnd.Dispose();hv__.Dispose();hv_Line1.Dispose();hv_Line2.Dispose();hv_Line3.Dispose();hv_RowV1.Dispose();hv_ColV1.Dispose();hv_IsOverlapping1.Dispose();hv_RowV2.Dispose();hv_ColV2.Dispose();hv_IsOverlapping2.Dispose();hv_RowV3.Dispose();hv_ColV3.Dispose();hv_IsOverlapping3.Dispose();hv_AB.Dispose();hv_AC.Dispose();hv_BC.Dispose();hv_cosAngleA.Dispose();hv_AngleA.Dispose();hv_cosAngleB.Dispose();hv_AngleB.Dispose();hv_cosAngleC.Dispose();hv_AngleC.Dispose();hv___Tmp_Ctrl_0_5.Dispose();hv___Tmp_Ctrl_0_6.Dispose();return new double[] { hv_AngleA,hv_AngleB,hv_AngleC };}}
}

主界面程序form1.cs

主界面代碼:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using HalconDotNet;
namespace halcon_cs
{public partial class Form1 : Form{HObject TestImage;public Form1(){InitializeComponent();}private void button2_Click(object sender, EventArgs e){using (OpenFileDialog openFileDialog = new OpenFileDialog()){openFileDialog.Filter = "所有文件|*.*";openFileDialog.Title = "選擇文件";if (openFileDialog.ShowDialog() == DialogResult.OK){string filePath = openFileDialog.FileName;textBox1.Text = filePath;}}}private void button1_Click(object sender, EventArgs e){//讀取文件HOperatorSet.ReadImage(out TestImage, textBox1.Text);//獲取圖片大小HTuple Width, Height;HOperatorSet.GetImageSize(TestImage, out Width, out Height);//設置圖片顯示范圍 hWindowControl1.HalconWindow獲得窗體句柄HOperatorSet.SetPart(hWindowControl1.HalconWindow, 0, 0, (Height - 1), (Width - 1)); //0,0, (Height - 1), (Width - 1)代表從0,0坐標到圖片的寬高坐標,達到全屏顯示//將圖片投射到窗體上HOperatorSet.DispObj(TestImage, hWindowControl1.HalconWindow);//將TestImage變量投射到句柄窗口上}private void button3_Click(object sender, EventArgs e){double[] result;HDevelopExport hDevelopExport = new HDevelopExport();result = hDevelopExport.action(textBox1.Text);foreach (double indexer in result) { textBox2.AppendText(indexer.ToString()+"\r\n");}}}
}

主界面設計:

using HalconDotNet;namespace halcon_cs
{partial class Form1{/// <summary>/// 必需的設計器變量。/// </summary>private System.ComponentModel.IContainer components = null;/// <summary>/// 清理所有正在使用的資源。/// </summary>/// <param name="disposing">如果應釋放托管資源,為 true;否則為 false。</param>protected override void Dispose(bool disposing){if (disposing && (components != null)){components.Dispose();}base.Dispose(disposing);}#region Windows 窗體設計器生成的代碼/// <summary>/// 設計器支持所需的方法 - 不要修改/// 使用代碼編輯器修改此方法的內容。/// </summary>private void InitializeComponent(){this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog();this.button2 = new System.Windows.Forms.Button();this.textBox1 = new System.Windows.Forms.TextBox();this.hWindowControl1 = new HalconDotNet.HWindowControl();this.button1 = new System.Windows.Forms.Button();this.button3 = new System.Windows.Forms.Button();this.textBox2 = new System.Windows.Forms.TextBox();this.SuspendLayout();// // openFileDialog1// this.openFileDialog1.FileName = "openFileDialog1";// // button2// this.button2.Location = new System.Drawing.Point(779, 41);this.button2.Name = "button2";this.button2.Size = new System.Drawing.Size(116, 43);this.button2.TabIndex = 4;this.button2.Text = "選擇文件";this.button2.UseVisualStyleBackColor = true;this.button2.Click += new System.EventHandler(this.button2_Click);// // textBox1// this.textBox1.Location = new System.Drawing.Point(314, 50);this.textBox1.Name = "textBox1";this.textBox1.Size = new System.Drawing.Size(459, 28);this.textBox1.TabIndex = 5;// // hWindowControl1// this.hWindowControl1.BackColor = System.Drawing.Color.Black;this.hWindowControl1.BorderColor = System.Drawing.Color.Black;this.hWindowControl1.ImagePart = new System.Drawing.Rectangle(0, 0, 640, 480);this.hWindowControl1.Location = new System.Drawing.Point(314, 110);this.hWindowControl1.Name = "hWindowControl1";this.hWindowControl1.Size = new System.Drawing.Size(555, 347);this.hWindowControl1.TabIndex = 6;this.hWindowControl1.WindowSize = new System.Drawing.Size(555, 347);// // button1// this.button1.Location = new System.Drawing.Point(229, 502);this.button1.Name = "button1";this.button1.Size = new System.Drawing.Size(177, 99);this.button1.TabIndex = 7;this.button1.Text = "顯示圖像";this.button1.UseVisualStyleBackColor = true;this.button1.Click += new System.EventHandler(this.button1_Click);// // button3// this.button3.Location = new System.Drawing.Point(722, 502);this.button3.Name = "button3";this.button3.Size = new System.Drawing.Size(183, 99);this.button3.TabIndex = 8;this.button3.Text = "計算角度";this.button3.UseVisualStyleBackColor = true;this.button3.Click += new System.EventHandler(this.button3_Click);// // textBox2// this.textBox2.Location = new System.Drawing.Point(280, 659);this.textBox2.Multiline = true;this.textBox2.Name = "textBox2";this.textBox2.Size = new System.Drawing.Size(588, 112);this.textBox2.TabIndex = 9;// // Form1// this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 18F);this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;this.ClientSize = new System.Drawing.Size(1176, 821);this.Controls.Add(this.textBox2);this.Controls.Add(this.button3);this.Controls.Add(this.button1);this.Controls.Add(this.hWindowControl1);this.Controls.Add(this.textBox1);this.Controls.Add(this.button2);this.Name = "Form1";this.Text = "Form1";this.ResumeLayout(false);this.PerformLayout();}#endregionprivate System.Windows.Forms.OpenFileDialog openFileDialog1;private System.Windows.Forms.Button button2;private System.Windows.Forms.TextBox textBox1;private HWindowControl hWindowControl1;private System.Windows.Forms.Button button1;private System.Windows.Forms.Button button3;private System.Windows.Forms.TextBox textBox2;}
}

4.案例三:缺陷檢測

如圖

一個四邊形,邊上有2個缺陷。要求:檢查出缺陷所在。

方法:先找到整體的輪廓,然后基于輪廓曲率的變化,來判斷缺陷。

halcon代碼:

read_image(Image, 'C:/Users/86957/Desktop/txqx.png')
rgb1_to_gray(Image, GrayImage)
get_image_size (Image, Width, Height)
dev_open_window (0, 0, Width, Height, 'black', WindowHandle)threshold(GrayImage, Regions, 0, 127)
select_shape (Regions, SelectedRegions, 'area', 'and', 'min', 99999)
* 提取邊界('inner' 表示內邊界,'outer' 表示外邊界)
boundary(SelectedRegions, RegionBorder, 'inner')* 設置綠色輪廓
dev_set_color('green')
dev_set_line_width(3)
* 顯示原始圖像
dev_display(GrayImage)
* 僅顯示綠色輪廓(不填充)
dev_display(RegionBorder)
*綠色輪廓是一個標準的四邊形。* 將區域邊界轉換為XLD輪廓
gen_contour_region_xld(RegionBorder, Contour, 'border')* 獲取輪廓點坐標
get_contour_xld(Contour, Rows, Cols)* 計算輪廓點的方向角度 (使用5點平滑)
get_contour_angle_xld (Contour, 'abs', 'range', 3, AngleValues)* 計算相鄰點的角度變化
tuple_length(AngleValues, NumPoints)
DiffAngles := []
for i := 1 to NumPoints-1 by 1* 處理角度跳變(π到-π)diff := abs(AngleValues[i] - AngleValues[i-1])if (diff > rad(180))diff := rad(360) - diffendifDiffAngles := [DiffAngles, diff]
endfor* 找出角度突變點 (閾值設為30度)
Threshold := rad(30)
DefectRows := []
DefectCols := []
for i := 1 to NumPoints-1 by 1if (DiffAngles[i-1] > Threshold)DefectRows := [DefectRows, Rows[i]]DefectCols := [DefectCols, Cols[i]]endif
endfor* 標記缺陷點
if (|DefectRows| > 0)gen_cross_contour_xld(Cross, DefectRows, DefectCols, 12, 0.785398)dev_set_color('red')dev_set_line_width(2)dev_display(Cross)
endif* 捕獲窗口內容
dump_window_image(ResultImage, WindowHandle)
*保存
*write_image(ResultImage, 'png', 0, 'C:/Users/86957/Desktop/result_image.png')
dev_close_window()

效果如下:

將halcon代碼輸出為c#,并修改輸入輸出。

返回HObject類型。
在返回前,關閉窗口,避免彈窗一直存在。


using HalconDotNet;
namespace halcon_cs
{public partial class HDevelopExport{public HObject action(string imgpath){// Local iconic variables HObject ho_Image, ho_GrayImage, ho_Regions;HObject ho_SelectedRegions, ho_RegionBorder, ho_Contour;HObject ho_Cross = null, ho_ResultImage;// Local control variables HTuple hv_Width = new HTuple(), hv_Height = new HTuple();HTuple hv_WindowHandle = new HTuple(), hv_Rows = new HTuple();HTuple hv_Cols = new HTuple(), hv_AngleValues = new HTuple();HTuple hv_NumPoints = new HTuple(), hv_DiffAngles = new HTuple();HTuple hv_i = new HTuple(), hv_diff = new HTuple(), hv_Threshold = new HTuple();HTuple hv_DefectRows = new HTuple(), hv_DefectCols = new HTuple();// Initialize local and output iconic variables HOperatorSet.GenEmptyObj(out ho_Image);HOperatorSet.GenEmptyObj(out ho_GrayImage);HOperatorSet.GenEmptyObj(out ho_Regions);HOperatorSet.GenEmptyObj(out ho_SelectedRegions);HOperatorSet.GenEmptyObj(out ho_RegionBorder);HOperatorSet.GenEmptyObj(out ho_Contour);HOperatorSet.GenEmptyObj(out ho_Cross);HOperatorSet.GenEmptyObj(out ho_ResultImage);ho_Image.Dispose();HOperatorSet.ReadImage(out ho_Image, imgpath);ho_GrayImage.Dispose();HOperatorSet.Rgb1ToGray(ho_Image, out ho_GrayImage);hv_Width.Dispose(); hv_Height.Dispose();HOperatorSet.GetImageSize(ho_Image, out hv_Width, out hv_Height);HOperatorSet.SetWindowAttr("background_color", "black");HOperatorSet.OpenWindow(0, 0, hv_Width, hv_Height, 0, "visible", "", out hv_WindowHandle);HDevWindowStack.Push(hv_WindowHandle);ho_Regions.Dispose();HOperatorSet.Threshold(ho_GrayImage, out ho_Regions, 0, 127);ho_SelectedRegions.Dispose();HOperatorSet.SelectShape(ho_Regions, out ho_SelectedRegions, "area", "and", "min",99999);//提取邊界('inner' 表示內邊界,'outer' 表示外邊界)ho_RegionBorder.Dispose();HOperatorSet.Boundary(ho_SelectedRegions, out ho_RegionBorder, "inner");//設置綠色輪廓if (HDevWindowStack.IsOpen()){HOperatorSet.SetColor(HDevWindowStack.GetActive(), "green");}if (HDevWindowStack.IsOpen()){HOperatorSet.SetLineWidth(HDevWindowStack.GetActive(), 3);}//顯示原始圖像if (HDevWindowStack.IsOpen()){HOperatorSet.DispObj(ho_GrayImage, HDevWindowStack.GetActive());}//僅顯示綠色輪廓(不填充)if (HDevWindowStack.IsOpen()){HOperatorSet.DispObj(ho_RegionBorder, HDevWindowStack.GetActive());}//綠色輪廓是一個標準的四邊形。//將區域邊界轉換為XLD輪廓ho_Contour.Dispose();HOperatorSet.GenContourRegionXld(ho_RegionBorder, out ho_Contour, "border");//獲取輪廓點坐標hv_Rows.Dispose(); hv_Cols.Dispose();HOperatorSet.GetContourXld(ho_Contour, out hv_Rows, out hv_Cols);//計算輪廓點的方向角度 (使用5點平滑)hv_AngleValues.Dispose();HOperatorSet.GetContourAngleXld(ho_Contour, "abs", "range", 3, out hv_AngleValues);//計算相鄰點的角度變化hv_NumPoints.Dispose();HOperatorSet.TupleLength(hv_AngleValues, out hv_NumPoints);hv_DiffAngles.Dispose();hv_DiffAngles = new HTuple();HTuple end_val34 = hv_NumPoints - 1;HTuple step_val34 = 1;for (hv_i = 1; hv_i.Continue(end_val34, step_val34); hv_i = hv_i.TupleAdd(step_val34)){//處理角度跳變(π到-π)hv_diff.Dispose();using (HDevDisposeHelper dh = new HDevDisposeHelper()){hv_diff = (((hv_AngleValues.TupleSelect(hv_i)) - (hv_AngleValues.TupleSelect(hv_i - 1)))).TupleAbs();}if ((int)(new HTuple(hv_diff.TupleGreater((new HTuple(180)).TupleRad()))) != 0){using (HDevDisposeHelper dh = new HDevDisposeHelper()){{HTupleExpTmpLocalVar_diff = ((new HTuple(360)).TupleRad()) - hv_diff;hv_diff.Dispose();hv_diff = ExpTmpLocalVar_diff;}}}using (HDevDisposeHelper dh = new HDevDisposeHelper()){{HTupleExpTmpLocalVar_DiffAngles = hv_DiffAngles.TupleConcat(hv_diff);hv_DiffAngles.Dispose();hv_DiffAngles = ExpTmpLocalVar_DiffAngles;}}}//找出角度突變點 (閾值設為30度)hv_Threshold.Dispose();using (HDevDisposeHelper dh = new HDevDisposeHelper()){hv_Threshold = (new HTuple(30)).TupleRad();}hv_DefectRows.Dispose();hv_DefectRows = new HTuple();hv_DefectCols.Dispose();hv_DefectCols = new HTuple();HTuple end_val47 = hv_NumPoints - 1;HTuple step_val47 = 1;for (hv_i = 1; hv_i.Continue(end_val47, step_val47); hv_i = hv_i.TupleAdd(step_val47)){if ((int)(new HTuple(((hv_DiffAngles.TupleSelect(hv_i - 1))).TupleGreater(hv_Threshold))) != 0){using (HDevDisposeHelper dh = new HDevDisposeHelper()){{HTupleExpTmpLocalVar_DefectRows = hv_DefectRows.TupleConcat(hv_Rows.TupleSelect(hv_i));hv_DefectRows.Dispose();hv_DefectRows = ExpTmpLocalVar_DefectRows;}}using (HDevDisposeHelper dh = new HDevDisposeHelper()){{HTupleExpTmpLocalVar_DefectCols = hv_DefectCols.TupleConcat(hv_Cols.TupleSelect(hv_i));hv_DefectCols.Dispose();hv_DefectCols = ExpTmpLocalVar_DefectCols;}}}}//標記缺陷點if ((int)(new HTuple((new HTuple(hv_DefectRows.TupleLength())).TupleGreater(0))) != 0){ho_Cross.Dispose();HOperatorSet.GenCrossContourXld(out ho_Cross, hv_DefectRows, hv_DefectCols,12, 0.785398);if (HDevWindowStack.IsOpen()){HOperatorSet.SetColor(HDevWindowStack.GetActive(), "red");}if (HDevWindowStack.IsOpen()){HOperatorSet.SetLineWidth(HDevWindowStack.GetActive(), 2);}if (HDevWindowStack.IsOpen()){HOperatorSet.DispObj(ho_Cross, HDevWindowStack.GetActive());}}//捕獲窗口內容ho_ResultImage.Dispose();HOperatorSet.DumpWindowImage(out ho_ResultImage, hv_WindowHandle);//保存//write_image (ResultImage, 'png', 0, 'C:/Users/86957/Desktop/result_image.png')HOperatorSet.CloseWindow(hv_WindowHandle);return ho_ResultImage;      }}
}

使用?HOperatorSet.CloseWindow(hv_WindowHandle);直接關閉彈窗。

主界面代碼:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using HalconDotNet;
namespace halcon_cs
{public partial class Form1 : Form{HObject TestImage;public Form1(){InitializeComponent();}private void button2_Click(object sender, EventArgs e){using (OpenFileDialog openFileDialog = new OpenFileDialog()){openFileDialog.Filter = "所有文件|*.*";openFileDialog.Title = "選擇文件";if (openFileDialog.ShowDialog() == DialogResult.OK){string filePath = openFileDialog.FileName;textBox1.Text = filePath;}}}private void button1_Click(object sender, EventArgs e){HDevelopExport hDevelopExport = new HDevelopExport();HObject result = hDevelopExport.action(textBox1.Text);//獲取圖片大小HTuple Width, Height;HOperatorSet.GetImageSize(result, out Width, out Height);//設置圖片顯示范圍 hWindowControl1.HalconWindow獲得窗體句柄HOperatorSet.SetPart(hWindowControl1.HalconWindow, 0, 0, (Height - 1), (Width - 1)); //0,0, (Height - 1), (Width - 1)代表從0,0坐標到圖片的寬高坐標,達到全屏顯示//將圖片投射到窗體上HOperatorSet.DispObj(result, hWindowControl1.HalconWindow);}}
}

運行后:

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/96119.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/96119.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/96119.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

大數據云原生是什么

"云原生"&#xff08;Cloud Native&#xff09;指的是?利用云計算原生優勢&#xff08;彈性、按需服務、自動化、分布式等&#xff09;來設計、構建、部署和運行大數據應用和工作負載的方法論與技術體系?。它不是簡單地“把大數據平臺搬到云上”&#xff0c;而是從…

Pytest項目_day16(yaml和parametrize結合)

查詢手機號歸屬地 我們首先可以在YAML文件中定義測試數據 方式一&#xff0c;使用- 注意&#xff1a;當我們需要一次傳入兩個參數時&#xff0c;需要定義兩層迭代&#xff0c;即兩層列表不夠直觀&#xff0c;容易寫錯 輸出的結果為&#xff1a; 然后我們可以將測試數據傳入test…

【Nginx指南】從核心原理到生產實踐

目錄Nginx指南&#xff1a;從核心原理到生產實踐引言&#xff1a;Nginx在現代架構中的核心地位一、Nginx核心能力與應用場景1.1 多場景適配的全能型中間件1.2 技術優勢&#xff1a;Nginx成為行業標準的關鍵二、Nginx安裝部署&#xff1a;源碼編譯與包管理方案2.1 源碼編譯&…

物體檢測

目錄 1 目標定位 2 地標檢測 3 目標檢測 4 在卷積網絡上實現滑動窗口 5 邊界框預測 6 交并比 7 非極大值抑制 8 錨框 9 YOLO算法 10 用u-net進行語義分割 11 轉置卷積 12 u-net 結構靈感 1 目標定位 你已經對圖片分類有所了解。例如通過這張圖片可以識…

es7.x es的高亮與solr高亮查詢的對比對比說明

一 solr&es高亮1.1 solr與es高亮功能解釋說明&#xff1a;1)高亮配置&#xff1a;fragmentSize(1000) 設置片段長度numOfFragments(1) 指定返回的片段數量preTags() 和 postTags() 設置高亮標記2)字段處理差異&#xff1a;在 ES 中&#xff0c;使用 matchQuery 而非 termQ…

DSP音頻算法工程師技能2

一、核心知識準備1. 算法原理3A算法&#xff08;AGC自動增益控制/AEC回聲消除/ANS降噪&#xff09;&#xff1a;掌握AEC的NLMS/雙講檢測原理&#xff0c;ANS的譜減法/維納濾波&#xff0c;AGC的壓縮曲線設計。熟悉Speex/WebRTC等開源實現。EQ音效&#xff1a;IIR/FIR濾波器設計…

第4章-04-用WebDriver頁面元素操作

??作者簡介,黑夜開發者,CSDN領軍人物,全棧領域優質創作者?,CSDN博客專家,阿里云社區專家博主,2023年CSDN全站百大博主。 ??數年電商行業從業經驗,歷任核心研發工程師,項目技術負責人。 ??本文已收錄于專欄:Web爬蟲入門與實戰精講,后續完整更新內容如下。 文章…

【計算機視覺與深度學習實戰】04基于K-Means聚類的圖像分割系統設計與實現

摘要 圖像分割作為計算機視覺領域的基礎任務,在目標檢測、醫學影像分析、自動駕駛等眾多應用中發揮著關鍵作用。本文基于K-Means聚類算法設計并實現了一個完整的圖像分割系統,該系統集成了多種顏色空間轉換、自定義初始化策略、空間特征融合等先進技術。通過Python和Tkinter…

Android Studio常用知識總結

一、運行方式1.運行 (Run)當您選擇“運行”時&#xff0c;Android Studio 會編譯您的應用并將其安裝到目標設備或模擬器上。這通常用于&#xff1a;快速部署: 您只想看看應用是否能正常啟動并運行&#xff0c;或者進行一些基礎的用戶界面測試。性能測試: 在正常運行模式下測試應…

設計模式筆記_行為型_訪問者模式

1. 訪問者模式介紹訪問者模式&#xff08;Visitor Pattern&#xff09;是一種行為型設計模式&#xff0c;它允許你在不改變對象結構的前提下&#xff0c;定義作用于這些對象的新操作。訪問者模式將操作的邏輯從對象結構中分離出來&#xff0c;使得你可以在運行時動態地添加新的…

數學建模 14 中心對數比變換

用途&#xff1a;是處理成分數據的核心預處理方法&#xff0c;核心目標是解決成分數據的和為常數100% &#xff0c; 導致的維度冗余&#xff0c;非線性相關問題。使得數據滿足傳統的統計/建模方法&#xff1b;舉例子&#xff1a;食品比例中 面粉(50%),糖(30%),水(20%)原理&…

【C語言強化訓練16天】--從基礎到進階的蛻變之旅:Day7

&#x1f525;個人主頁&#xff1a;草莓熊Lotso &#x1f3ac;作者簡介&#xff1a;C研發方向學習者 &#x1f4d6;個人專欄&#xff1a; 《C語言》 《數據結構與算法》《C語言刷題集》《Leetcode刷題指南》 ??人生格言&#xff1a;生活是默默的堅持&#xff0c;毅力是永久的…

污水處理行業的 “智能革命”:邊緣計算網關如何重塑傳統運維模式?

污水處理行業的 “智能革命”&#xff1a;邊緣計算網關如何重塑傳統運維模式&#xff1f;在污水處理這一關乎生態環境與可持續發展的關鍵領域&#xff0c;藍蜂網關正憑借其先進技術與強大功能&#xff0c;發揮著無可替代的重要作用。作為工業級物聯網解決方案的核心組件&#x…

ASP.NET Core 中的多租戶 SaaS 應用程序

介紹隨著軟件即服務 (SaaS) 持續主導技術領域&#xff0c;構建能夠高效地從單一代碼庫服務于多位客戶&#xff08;租戶&#xff09;的應用程序變得至關重要。ASP.NET Core 憑借其模塊化和可擴展的架構&#xff0c;是實現多租戶 SaaS 應用程序的強大框架。本文將指導您了解構建多…

JUC之CompletableFuture【中】

文章目錄四、CompletableFuture基本使用4.1 默認線程池、無返回值4.2 默認線程池、有返回值4.3 自定義線程池、有返回值4.4 CompletableFuture 獲取結果五、對結果進行處理5.1 方法說明5.2 示例5.3 thenApply vs thenApplyAsync5.3.1 核心區別: 執行線程不同5.3.2 thenApply: 同…

環境變量不生效?

目錄 添加環境變量 解決不生效 不生效場景 解決辦法 大家都知道Windows系統對于開發者來說并不友好&#xff0c;尤其是新手&#xff0c;當然這是相比于linux和MacOS相比&#xff0c;因為開發工具、項目腳本等環境配置要為復雜&#xff0c;注意事項也更多一些。而這篇文章將…

小迪安全v2023學習筆記(六十六講)—— Java安全SQL注入SSTISPELXXE

文章目錄前記WEB攻防——第六十六天Java安全&SPEL表達式&SSTI模板注入&XXE&JDBC&MyBatis注入環境搭建Hello-Java-SecJavaSecJava安全 - SQL注入-JDBC&MyBatisJDBC注入原理語句拼接預編譯的錯誤使用JdbcTemplate正則過濾MyBatis注入原理Like注入Order B…

把 AI 變成「圖書館管理員」——基于檢索增強的離線圖書語音導航小盒子

標簽&#xff1a;檢索增強、語音導航、離線 LLM、RAG、ESP32-S3、低功耗、TTS、BLE ---- 1. 背景&#xff1a;讀者找不到書的痛苦 高校圖書館每天 5000 人次&#xff0c;高頻問題&#xff1a; ? “《深度學習》在哪個書架&#xff1f;” ? “有沒有類似《三體》的科幻&…

架構思維:在AI時代為產品“減負”的終極武器——用結構化智慧破解數字化復雜困局

摘要 數字化產品的復雜度飆升已成為企業發展的核心瓶頸。本文基于架構思維的本質&#xff08;元素、連接、演進&#xff09;&#xff0c;結合5A架構體系&#xff08;業務/信息/應用/技術/治理架構&#xff09;&#xff0c;系統闡述如何通過分而治之、共性沉淀、AI賦能三大策略降…

黎陽之光:以數字之力,筑牢流域防洪“智慧防線”

當洪水來襲&#xff0c;每一分精準的預報、每一次及時的預警、每一輪科學的預演、每一套完善的預案&#xff0c;都可能關系到江河安瀾與萬家平安。在水利現代化建設的浪潮中&#xff0c;黎陽之光憑借數字孿生、視頻孿生等核心技術&#xff0c;打造流域防洪“四預”管理平臺&…