实用指南:基于Halcon深度学习之分类

********环境准备******系统:win7以上系统***显卡:算力3.0以上***显卡驱动:10.1以上版本(nvidia-smi查看指令) ***读取深度学习模型***read_dl_model ('pretrained_dl_classifier_compact.hdl', DLModelHandle)***获取模型中的图象张量及对应的灰度值范围get_dl_model_param (DLModelHandle, 'image_width', ImgWidth)get_dl_model_param (DLModelHandle, 'image_height', ImgHeight)get_dl_model_param (DLModelHandle, 'image_num_channels', ImgChannel)get_dl_model_param (DLModelHandle, 'image_range_min', ImgRangMin)get_dl_model_param (DLModelHandle, 'image_range_max', ImgRangMax)  ************预处理数据准备及拆分**********classNames := ['1-2','1-3','1-4','2-4','3-5','4-7','5-6']rawImageFolders := '../images/' + classNames***把原图像数据转换为对应的Dataset格式***read_dl_dataset_classification (rawImageFolders, 'last_folder', DLDataset)***对数据集进行拆分***trainPrecent := 60 // 用于训练的比例validdatatPrecent := 20 // 用于测试的比例GenSplitParam := dict{overwrite_split:'true'}split_dl_dataset (DLDataset, trainPrecent, validdatatPrecent, GenSplitParam)***预处理数据****1、创建预处理参数** 预处理数据存储路径processFolder := 'ProcessData'** 定义预处理参数文件路径dlProcessFileName := processFolder + '/dl_preprocess_param.hdict'** 检查文件是否存在file_exists (processFolder, FileExists)if(not FileExists)    make_dir (processFolder)endif** 创建预处理参数create_dl_preprocess_param ('classification', ImgWidth, ImgHeight, ImgChannel, \                            ImgRangMin, ImgRangMax, 'none', 'full_domain',\                            [], [], [], [], DLPreprocessParam)** 对数据进行预处理GenParam := dict{overwrite_files:'true'}preprocess_dl_dataset (DLDataset, processFolder, DLPreprocessParam, \                       GenParam, DLDatasetFileName)** 保存预处理参数文件write_dict (DLPreprocessParam, dlProcessFileName, [], []) ************使用预处理数据对模型进行训练************** 总周期(所有图片训练一次为一个周期)numEpochs := 100** 批次数(一个周期本分割的份数)batchSize := 5** 评估周期(每训练几个周期进行一次评估)evluationIntervalEphochs := 2** 学习率learningRate := 0.001**** 设置模型参数set_dl_model_param(DLModelHandle, 'class_names', classNames)set_dl_model_param(DLModelHandle, 'image_dimensions', [ImgWidth,ImgHeight,ImgChannel])set_dl_model_param(DLModelHandle, 'learning_rate', learningRate)set_dl_model_param (DLModelHandle, 'batch_size', batchSize)** 设置增强参数GenParamName := []GenParamValue := []** 定义参数字典,增强参数augmentParam := dict{}augmentParam.augmentation_percentage := 100augmentParam.mirror := 'rc'GenParamName := [GenParamName,'augment']GenParamValue := [GenParamValue,augmentParam] ** 定义存储最佳模型路径和最终模型路径augmentBest := dict{}augmentBest.type := 'best'augmentBest.basename := processFolder + '/model_best'GenParamName := [GenParamName,'serialize']GenParamValue := [GenParamValue,augmentBest] augmentFinal := dict{}augmentFinal.type := 'final'augmentFinal.basename := processFolder + '/model_final'GenParamName := [GenParamName,'serialize']GenParamValue := [GenParamValue,augmentFinal]** 创建训练参数及执行训练create_dl_train_param (DLModelHandle, numEpochs, evluationIntervalEphochs, \                       'true', 32, GenParamName, GenParamValue, TrainParam)** 执行模型训练train_dl_model (DLDataset, DLModelHandle, TrainParam, 0,\                TrainResults, TrainInfos, EvaluationInfos)** 释放资源clear_dl_model (DLModelHandle)** 关闭训练窗口stop()dev_close_window()dev_close_window() ***********模型评估************* 定义评估模型文件路径retainModelFile := processFolder + '/model_best.hdl'** 读取训练后的模型read_dl_model (retainModelFile, RetainDLModelHandle)** 定义评估的指标evaluateGenParam := ['f_score','recall','precision','absolute_confusion_matrix',\                     'relative_confusion_matrix']evaluateDict := dict{measures:evaluateGenParam}** 执行模型评估evaluate_dl_model(DLDataset, RetainDLModelHandle, 'split', 'test', \                  evaluateDict, EvaluationResult, EvalParams)** 显示评估结果GenDispParam := dict{}GenDispParam.display_mode := ['measures','pie_charts_recall','pie_charts_precision',\                              'absolute_confusion_matrix','relative_confusion_matrix']WindowHandleDict := dict{}dev_display_classification_evaluation(EvaluationResult, EvalParams,\                                      GenDispParam, WindowHandleDict)stop()dev_close_window_dict(WindowHandleDict)  ***********模型推断************* 读取推断数据list_image_files('../test_image','bmp',[],ImageFiles)** 读取预处理参数read_dict(dlProcessFileName,[],[],DLPreprocessParam)** 设置显示字体大小dev_get_window(WindowHandle)set_display_font(WindowHandle, 26, 'mono', 'true', 'false')** 循环检测每一张图像for Index :=0 to |ImageFiles| -1 by 1    ** 获取当前图像    read_image(Image,ImageFiles[Index])    ** 生产样本图像    gen_dl_samples_from_images(Image, DLSampleBatch)    ** 把推断图像处理成预处理图像数据    preprocess_dl_samples(DLSampleBatch, DLPreprocessParam)    **  使用模型进行推断类别    apply_dl_model(RetainDLModelHandle, DLSampleBatch, [], DLResultBatch)    ** 评估结果显示    className := DLResultBatch.classification_class_names[0]    score := DLResultBatch.classification_confidences[0]    ** 显示图像上面    dev_disp_text('类别:'+className+',分数:'+score, 'window',\                  'top', 'left', 'white', 'box_color', 'forest green')    stop()endfor clear_dl_model(RetainDLModelHandle)

以上为halcon源码,联合C#编程操作界面

C#源码

///         /// 分类类别名称        ///         private HTuple classNames;         ///         /// 模型文件        ///         public string[] ModelFiles { get; private set; }         #region 主界面相关事件        public HomePage()        {            InitializeComponent();        }         private void HomePage_FormClosing(object sender, FormClosingEventArgs e)        {        }        private void HomePage_Load(object sender, System.EventArgs e)        {                       // UI 显示日志            ViewAppender viewAppender = new ViewAppender(dgvLog)            {                Location = "",            };            LogCombiner.Ins.Append(viewAppender);            // 初始化网络模型            InitializeModels();             // 模型评估默认参数            // recall            cbMetric.SelectedIndex = 0;            // test            cbSampleSelectValues.SelectedIndex = 0;        }        #endregion         #region 设置HWindowControl控件的显示方式        private void DispImage(HImage image, HWindow window)        {            int imageWidth, imageHeight, winRow, winCol, winWidth, winHeight, partWidth, partHeight;            try            {                image.GetImageSize(out imageWidth, out imageHeight);                window.GetWindowExtents(out winRow, out winCol, out winWidth, out winHeight);                if (winWidth > winHeight)                {                    partWidth = imageWidth;                    partHeight = imageWidth * winHeight / winWidth;                }                else                {                    partWidth = imageHeight * winWidth / winHeight;                    partHeight = imageHeight;                }                 // 设置显示图像在窗口中间                var offsetX = (imageWidth - partWidth) / 2;                var offsetY = (imageHeight - partHeight) / 2;                // 设置窗口显示区域                HOperatorSet.SetPart(window, offsetY, offsetX, partHeight + offsetY - 1, partWidth + offsetX - 1);                // 显示图形                HOperatorSet.DispObj(image, window);            }            catch (HalconException hEx)            {                MessageBox.Show(hEx.Message);            }        }         ///         /// 把HObject转化为对应的HImage方法        ///         ///         ///         private HImage HObject2HImage(HObject hObject)        {            HImage image = new HImage();            // 获取当前传人对象的通道数【灰度/彩色】            HOperatorSet.CountChannels(hObject, out var channels);            if (channels.I == 0)            {                return image;            }            // 判断通道数            if (channels.I == 1)            {                // 获取传人图形的数据                HOperatorSet.GetImagePointer1(hObject,                    out var pointer, out var type, out var width, out var height);                // 生成当通道图形                image.GenImage1(type, width, height, pointer);            }            else            {                // 彩色图                HOperatorSet.GetImagePointer3(hObject, out var pointerRed, out var pointerGreen,                    out var pointerBlue, out var type, out var width, out var height);                image.GenImage3(type, width, height, pointerRed, pointerGreen, pointerBlue);            }             return image;        }        #endregion         #region 加载模型文件选择下拉框        private void InitializeModels()        {            // 获取项目编译路径            ModelFiles = Directory.GetFiles(Path.Combine(Directory.GetCurrentDirectory(), "hdl"),"*.hdl");            // 把模型文件添加至下拉框中            foreach(string modelFile in ModelFiles)            {                // 获取模型文件名                string modelName = Path.GetFileNameWithoutExtension(modelFile);                // 添加到下拉列表                cbBackBone.Items.Add(modelName);            }            // 判断是否有模型文件            if(ModelFiles.Length > 0)            {                // 默认选择第一个文件                cbBackBone.SelectedIndex = 0;                Logger.Notify("model load finished .", "Preprocess");            }            else            {                // 如果没有模型文件,下拉框禁用                cbBackBone.Enabled = false;                Logger.Warn("model files not found .", "Preprocess");            }        }        #endregion         #region 读取模型参数        private void cbBackBone_SelectedIndexChanged(object sender, EventArgs e)        {            try            {                // 读取选择的网络模型文件                string modelFile = ModelFiles[cbBackBone.SelectedIndex];                // 加载模型 read_dl_model                HOperatorSet.ReadDlModel(modelFile, out var dLModelHandle);                // 判断模型不为空                if(dLModelHandle == null)                {                    Logger.Warn("read_dl_model failure .", "Preprocess");                    return;                }                // 读取模型张量数                HOperatorSet.GetDlModelParam(dLModelHandle, "image_width", out HTuple imageWidth);                HOperatorSet.GetDlModelParam(dLModelHandle, "image_height", out HTuple imageHeight);                HOperatorSet.GetDlModelParam(dLModelHandle, "image_num_channels", out HTuple imageChannels);                HOperatorSet.GetDlModelParam(dLModelHandle, "image_range_min", out HTuple imageRangMin);                HOperatorSet.GetDlModelParam(dLModelHandle, "image_range_max", out HTuple imageRangMax);                // 数据填充至对应文本框                tbImgWidth.Text = imageWidth.ToString();                tbImgHeight.Text = imageHeight.ToString();                tbChannel.Text = imageChannels.ToString();                tbGrayMin.Text = imageRangMin.ToString();                tbGrayMax.Text = imageRangMax.ToString();                 // 释放加载的模型                HOperatorSet.ClearDlModel(dLModelHandle);                dLModelHandle.Dispose();                dLModelHandle = null;            }            catch (Exception ex)            {                Logger.Error(ex.Message, "Preprocess");            }        }        #endregion         #region 选择样本路径和存储路径        private void btnSelectRawPath_Click(object sender, EventArgs e)        {            using (FolderBrowserDialog dlg = new FolderBrowserDialog())            {                if (dlg.ShowDialog() == DialogResult.OK)                {                    // 重新创建,防止重复添加                    classNames = new HTuple();                    tbRawPath.Text = dlg.SelectedPath;                    // 获取选择文件夹下面的所有文件夹名称                    string[] folder = Directory.GetDirectories(tbRawPath.Text);                    // 把文件夹名添加到元组中                    foreach (var item in folder)                    {                        classNames.Append(new DirectoryInfo(item).Name);                    }                }            }        }         private void btnSelectPrePath_Click(object sender, EventArgs e)        {            using (FolderBrowserDialog dlg = new FolderBrowserDialog())            {                if (dlg.ShowDialog() == DialogResult.OK)                {                    tbPreStorPath.Text = dlg.SelectedPath;                }            }        }        #endregion         #region 执行数据预处理操作        private async void btnExecPreprocess_Click(object sender, EventArgs e)        {            // 获取预处理对象            var preprocess = Classification.ProcessAction;            // 绑定更新方法            preprocess.UpdateImageAction += Preprocess_UpdateImageAction;             // 获取界面的参数            var imageWith = Convert.ToInt32(tbImgWidth.Text);            var imageHeight = Convert.ToInt32(tbImgHeight.Text);            var imageNumChannels = Convert.ToInt32(tbChannel.Text);            var imageRangeMin = Convert.ToInt32(tbGrayMin.Text);            var imageRangeMax = Convert.ToInt32(tbGrayMax.Text);            var backBoneFileName = ModelFiles[cbBackBone.SelectedIndex];            var rawImagePath = tbRawPath.Text;            var preprocessPath = tbPreStorPath.Text;             // 设置到预处理对象属性中            preprocess.ImageHeight = imageHeight;            preprocess.ImageWidth = imageWith;            preprocess.ImageNumChannels = imageNumChannels;            preprocess.ImageRangeMin = imageRangeMin;            preprocess.ImageRangeMax = imageRangeMax;            preprocess.BackBonePath = backBoneFileName;            preprocess.PreProcessPath = preprocessPath;            preprocess.SamplesPath = rawImagePath;            // 设置分类名称            preprocess.ClassNames = classNames;            // 界面显示信息            HalconDLTool.set_display_font(hWinPre.HalconWindow, 20, "mono", "true", "false");            // 调用预处理对象的预处理方法            var res = await preprocess.ExecutePreProcess();            // 判断执行结果            if (res > 0)            {                HOperatorSet.DispText(hWinPre.HalconWindow, "Preprocess finished .", "window", 12, 12, "white", "box_color", "forest green");                Logger.Notify("Preprocess finished .", "Preprocess");            }            else            {                HOperatorSet.DispText(hWinPre.HalconWindow, "Preprocess failure .", "window", 12, 12, "white", "box_color", "red");                Logger.Error("Preprocess failure .", "Preprocess");            }        }        ///         ///         ///         ///         ///         private void Preprocess_UpdateImageAction(HObject obj)        {            try            {                if (obj != null)                {                    var hw = hWinPre.HalconWindow;                    hw.ClearWindow();                    hw.SetWindowParam("flush", "false");                    DispImage(HObject2HImage(obj), hw);                    hw.FlushBuffer();                }            }            catch (Exception)            {                 throw;            }        }        #endregion         #region 选择训练的数据集文件        private string SelectFile(string filter)        {            using(OpenFileDialog dlg = new OpenFileDialog())            {                dlg.Filter = filter;                if(dlg.ShowDialog() == DialogResult.OK)                {                    return dlg.FileName;                }                return null;            }        }        private void btnSelectData_Click(object sender, EventArgs e)        {            // 获取选择的数据集文件路径            string datasetFile = SelectFile("Dataset(*.hdict)|*.hdict");            // 把数据集路径存放至控件的Tag属性,并显示文件名称            tbDataPath.Tag = datasetFile;            if(datasetFile != null)            {                // 将数据集名称显示至文本框                tbDataPath.Text = Path.GetFileNameWithoutExtension(datasetFile);            }            //  获取当前文件所在的路径,模型文件也在当前目录下            Classification.TrainingAction.ModelFilePath = Path.GetDirectoryName(datasetFile);        }        #endregion         #region 执行模型训练        private async void btnTrain_Click(object sender, EventArgs e)        {            // 获取训练对象            var training = Classification.TrainingAction;            // 获取界面的数据            var batchSize = Convert.ToInt32(tbBatchSize.Text);            var learningRate = Convert.ToDouble(tbLearningRate.Text);            var numEpochs = Convert.ToInt32(tbNumEpochs.Text);            var evaluateNumEpochs = Convert.ToInt32(tbEvluationIntervalEphochs.Text);            var trainingPrecent = Convert.ToInt32(tbTrainPrecent.Text);            var validationPercent = Convert.ToInt32(tbValiddatatPrecent.Text);            // 设置训练对象的属性            training.TraingPercent = trainingPrecent;            training.ValidationPercent = validationPercent;            training.BatchSize = batchSize;            training.LearningRate = learningRate;            training.NumEpochs = numEpochs;            training.EvaluateNumEpoch = evaluateNumEpochs;            // 设置显示窗口的的背景            var hw = hWinTrain.HalconWindow;            hw.SetWindowParam("background_color", "light gray");            training.TrainWindow = hw;             // 调用模型训练的方法            int res = await training.ExecuteTraining();             if (res > 0)            {                Logger.Notify("training finished .", "Training");            }            else            {                Logger.Error("training exception .", "Training");            }        }        #endregion         #region 执行评估        private void btnEvaluate_Click(object sender, EventArgs e)        {            // 获取评估对象并给属性赋值            var evaluate = Classification.EvaluateAction;            evaluate.EvaluateMetric = cbMetric.Text;            evaluate.EvaluateDataName = cbSampleSelectValues.Text;            evaluate.EvaluateWindow = hWinEvaluate.HalconWindow;             // 执行模型评估            int res = evaluate.ExecuteEvaluate();             if (res > 0)            {                Logger.Notify("evaluate finished .", "Evaluate");            }            else            {                Logger.Error("evaluate error .", "Evaluate");            }        }        private void btnSelectEvaluateModel_Click(object sender, EventArgs e)        {            // 获取选择的数据集文件路径            string datasetFile = SelectFile("Model(*.hdl)|*.hdl");            if (datasetFile != null)            {                // 将数据集名称显示至文本框                tbEvaluateModelFile.Text = Path.GetFileNameWithoutExtension(datasetFile);            }            // 设置完成的模型路径            Classification.EvaluateAction.EvaluateModelFileName = datasetFile;        }        #endregion         #region 执行推断        private void btnSelectInferModel_Click(object sender, EventArgs e)        {            // 获取选择的数据集文件路径            string datasetFile = SelectFile("Model(*.hdl)|*.hdl");            // 把数据集路径存放至控件的Tag属性,并显示文件名称            tbInferModel.Tag = datasetFile;            if (datasetFile != null)            {                // 将数据集名称显示至文本框                tbInferModel.Text = Path.GetFileNameWithoutExtension(datasetFile);            }            // 设置推断使用的模型文件            Classification.InferenceAction.ModelTypeName = datasetFile;        }        private void btnSelectInferImg_Click(object sender, EventArgs e)        {             var dialog = new FolderBrowserDialog();            if (dialog.ShowDialog() == DialogResult.OK)            {                // 获取用户选择的目录                var inferDataPath = dialog.SelectedPath;                // 给文本框赋值                tbInferPath.Text = inferDataPath;                // 设置推断文件,这里可以进行优化文件后缀,避免放置非图像文件                Classification.InferenceAction.InferImages = Directory.GetFiles(inferDataPath).ToList();            }        }        private async void btnSigInfer_Click(object sender, EventArgs e)        {            // 获取推断对象            var infer = Classification.InferenceAction;            infer.UpdateInvoker += InferOnece_UpdateInvoker;             // 调用推断方法            int res = await infer.ExecuteInfer(InferType.ONECE);             if (res > 0)            {                // 赋值推断结果                tbClass.Text = infer.Class;                tbScore.Text = (infer.Score*100).ToString("F2");                tbTicks.Text = (infer.Ticks * 1000).ToString("F4");                Logger.Log($"{infer.Index}.Type:{infer.Class},Score:{(infer.Score * 100).ToString("F2")}", "Inference");            }            else            {                Logger.Log("infer method error.", "Inference");            }        }         private void InferOnece_UpdateInvoker(HObject obj)        {            if (obj != null)            {                var hw = hWinInfer.HalconWindow;                // 关闭窗口缓存更新                hw.SetWindowParam("flush", "false");                // 把上一次窗口显示数据清空                hw.ClearWindow();                // 显示采集图像                DispImage(HObject2HImage(obj), hw);                // 更新创建数据                hw.FlushBuffer();            }        }         private async void btnContinueInfer_Click(object sender, EventArgs e)        {            // 获取推断对象            var infer = Classification.InferenceAction;            infer.ContinueUpdateInvoker += InferContinue_UpdateInvoker;             // 调用推断方法            int res = await infer.ExecuteInfer(InferType.CONTINUE);             if (res > 0)            {                // 赋值推断结果                Logger.Notify("continue inference finished.", "Inference");            }            else            {                Logger.Log("continue infer method error.", "Inference");            }        }         private void InferContinue_UpdateInvoker(HObject obj, Inference inference)        {            if (obj != null)            {                var hw = hWinInfer.HalconWindow;                // 关闭窗口缓存更新                hw.SetWindowParam("flush", "false");                // 把上一次窗口显示数据清空                hw.ClearWindow();                // 显示采集图像                DispImage(HObject2HImage(obj), hw);                // 更新创建数据                hw.FlushBuffer();                 // 多线程中调用必须使用异步调用方式                BeginInvoke(new Action(() =>                {                    // 赋值推断结果                    tbClass.Text = inference.Class;                    tbScore.Text = (inference.Score*100).ToString("F2");                    tbTicks.Text = (inference.Ticks * 1000).ToString("F4");                }));                Logger.Log($"{inference.Index}.Type:{inference.Class},Score:{(inference.Score * 100).ToString("F2")}", "Inference");            }        }        #endregion

完整打包资料资料包​​​​​​​

posted @ 2025-07-21 21:55  yfceshi  阅读(35)  评论(0)    收藏  举报