halcon机器视觉深度学习对象检测,物体检测
目录
- 效果图
- 操作步骤
- 软件版本
- halcon参考代码
- 本地函数 get_distinct_colors()
- 本地函数 make_neighboring_colors_distinguishable()
效果图
操作步骤
首先要在Deep Learning Tool工具里面把图片打上标注文本,
然后训练模型,导出模型文件
这个是模型
model_训练-250215-111516_opt.hdl
模型配置参数
model_训练-250215-111516_opt_dl_preprocess_params.hdict
软件版本
- 使用的版本 halcon 23.11
- Deep Learning Tool-24.05.1
halcon参考代码
*
* Inference can be done on a GPU or CPU.
* See the respective system requirements in the Installation Guide.
* If possible a GPU is used in this example.
* In case you explicitly wish to run this example on the CPU,
* choose the CPU device instead.
query_available_dl_devices (['runtime', 'runtime'], ['gpu', 'cpu'], DLDeviceHandles)
if (|DLDeviceHandles| == 0)throw ('No supported device found to continue this example.')
endif
* Due to the filter used in query_available_dl_devices, the first device is a GPU, if available.
*第一个设备是 GPU(如果可用)
DLDevice := DLDeviceHandles[0]
* * *************************************************
* ** 设置推理路径和参数 ***
* *************************************************
*
* 我们将对示例图像进行推理。
* 在实际应用程序中,新传入的图像(不用于训练或评估)
* 将在此处使用。
*
* 在此示例中,我们从 file 中读取图像。* 用我训练的图片
ImageDir := 'G:/机器视觉_测试项目/家具目标检测/images - 副本'*
* Set the paths of the retrained model and the corresponding preprocessing parameters.
* Example data folder containing the outputs of the previous example series.
ExampleDataDir := 'detect_pills_data'* Use the pretrained model and preprocessing parameters shipping with HALCON.*使用 HALCON 附带的预训练模型和预处理参数。*PreprocessParamFileName := 'detect_pills_preprocess_param.hdict'* RetrainedModelFileName := 'detect_pills.hdl'*whl 测试我自己训练的模型和参数,图片配置dir1223:='G:/机器视觉_测试项目/家具目标检测/'imgConfigHdict:='model_训练-250215-111516_opt_dl_preprocess_params.hdict'PreprocessParamFileName:= dir1223+imgConfigHdict*识别模型* RetrainedModelFileName := dir1223+ 'best_model.hdl'RetrainedModelFileName :=dir1223+ 'model_训练-250215-111516_opt.hdl'*
* Batch Size used during inference.推理批次大小
BatchSizeInference := 1
*
* Postprocessing parameters for the detection model.检测模型的后处理参数。
MinConfidence := 0.6
MaxOverlap := 0.2
MaxOverlapClassAgnostic := 0.7
*
* ********************
* ** 推理 ***
* ********************
*
* Check if all necessary files exist.
*check_data_availability (ExampleDataDir, PreprocessParamFileName, RetrainedModelFileName, UsePretrainedModel)
*
* 读取重新训练的模型。
read_dl_model (RetrainedModelFileName, DLModelHandle)
*
* Set the batch size. 设置批处理大小。
set_dl_model_param (DLModelHandle, 'batch_size', BatchSizeInference)
*
* Initialize the model for inference.初始化模型以进行推理。
set_dl_model_param (DLModelHandle, 'device', DLDevice)
*
* Set postprocessing parameters for model.设置模型的后处理参数。
set_dl_model_param (DLModelHandle, 'min_confidence', MinConfidence)
set_dl_model_param (DLModelHandle, 'max_overlap', MaxOverlap)
set_dl_model_param (DLModelHandle, 'max_overlap_class_agnostic', MaxOverlapClassAgnostic)
*
* Get the parameters used for preprocessing.获取用于预处理的参数。
read_dict (PreprocessParamFileName, [], [], DLPreprocessParam)
* * 使用显示所需的数据集参数创建字典。
DLDataInfo := dict{}
get_dl_model_param (DLModelHandle, 'class_names', ClassNames)* 目标对象,标签名称
DLDataInfo.class_names := ClassNames
get_dl_model_param (DLModelHandle, 'class_ids', ClassIDs)
DLDataInfo.class_ids := ClassIDs
* 设置可视化的通用参数。
GenParam := dict{scale_windows: 1.2,display_labels:true}*读取目录里面的若干图片文件list_files (ImageDir, ['files' ], ImageFiles)*获取图片尺寸,whl测试read_image(img1,ImageFiles[0]) get_image_size (img1, Width, Height)* dev_open_window (1, 1, Width, Height, 'black', WindowID1)dev_open_window (1, 1, 900, 900*Height/(Width*1.0), 'black', WindowID1)*视频文件读取*grab_image_from_video()* open_framegrabber()* 读取视频帧
*grab_image_start([])
*grab_image(Image)
*grab_image_stop([])*
* 以 BatchSizeInference 大小批量循环访问所有图像以进行推理
for BatchIndex := 0 to floor(|ImageFiles| / real(BatchSizeInference)) - 1 by 1* * Get the paths to the images of the batch.Batch := ImageFiles[BatchIndex * BatchSizeInference:(BatchIndex + 1) * BatchSizeInference - 1]* 读取图片read_image (ImageBatch, Batch)* * Generate the DLSampleBatch.gen_dl_samples_from_images (ImageBatch, DLSampleBatch)* * Preprocess the DLSampleBatch.preprocess_dl_samples (DLSampleBatch, DLPreprocessParam)* * 在 DLSampleBatch 上应用 DL 模型。apply_dl_model (DLModelHandle, DLSampleBatch, [], DLResultBatch)* * Postprocessing and visualization.后处理和可视化* Loop over each sample in the batch.循环处理批次中的每个样品for SampleIndex := 0 to BatchSizeInference - 1 by 1* * Get sample and according results.获取样本和相应的结果。DLSample := DLSampleBatch[SampleIndex]DLResult := DLResultBatch[SampleIndex]* *whl测试
KeysForDisplay:='bbox_result'* * 显示检测结果.* dev_display_dl_data (DLSample, DLResult, DLDataInfo, 'bbox_result', GenParam, WindowHandleDict)*whl测试,ocr_detection_score_map_character*
* This procedure displays the content of the provided DLSample and/or DLResult
* depending on the input string KeysForDisplay.
* DLDatasetInfo is a dictionary containing the information about the dataset.
* The visualization can be adapted with GenParam.
*
* ** Set the default values: ***
Params := dict{}
*
* Define the screen width when a new window row is started.
Params.threshold_width := 1024
* Since potentially a lot of windows are opened,
* scale the windows consistently.
Params.scale_windows := 0.8
* Set a font and a font size.
Params.font := 'mono'
Params.font_size := 14
*
Params.line_width := 2
Params.map_transparency := 'cc'
Params.map_color_bar_width := 140
*
* Define parameter values specifically for 3d_gripping_point_detection
Params.gripping_point_color := '#00FF0099'
Params.gripping_point_size := 6
Params.region_color := '#FF000040'
Params.gripping_point_map_color := '#83000080'
Params.gripping_point_background_color := '#00007F80'
*
* Define parameter values specifically for anomaly detection
* and Global Context Anomaly Detection.
Params.anomaly_region_threshold := -1
Params.anomaly_classification_threshold := -1
Params.anomaly_region_label_color := '#40e0d0'
Params.anomaly_color_transparency := '40'
Params.anomaly_region_result_color := '#ff0000c0'
*
* Define segmentation-specific parameter values.
Params.segmentation_max_weight := 0
Params.segmentation_draw := 'fill'
Params.segmentation_transparency := 'aa'
Params.segmentation_exclude_class_ids := []
*
* Define bounding box-specific parameter values.
Params.bbox_label_color := '#000000' + '99'
Params.bbox_display_confidence := 1
Params.bbox_text_color := '#eeeeee'
*
* By default, display a description on the bottom.
Params.display_bottom_desc := true
*
* By default, show a legend with class IDs.
Params.display_legend := true
*
* By default, show the anomaly ground truth regions.
Params.display_ground_truth_anomaly_regions := true
*
* By default, show class IDs and color frames for classification ground truth/results.
Params.display_classification_ids := true
Params.display_classification_color_frame := true
*
* By default, show class labels for detection ground truth/results.
Params.display_labels := true
*
* By default, show direction of the ground truth/results instances for detection with instance_type 'rectangle2'.
Params.display_direction := true
*
* By default, use color scheme 'Jet' for the heatmap display.
Params.heatmap_color_scheme := 'jet'
* ** Set user-defined values: ***
*
* Overwrite default values by given generic parameters.
if (GenParam != [])get_dict_param (GenParam, 'keys', [], GenParamNames)for ParamIndex := 0 to |GenParamNames| - 1 by 1GenParamName := GenParamNames[ParamIndex]get_dict_param (Params, 'key_exists', GenParamName, KeyExists)if (not KeyExists)throw ('Unknown generic parameter: ' + GenParamName + '.')endifParams.[GenParamName] := GenParam.[GenParamName]endfor
endif
*
if (|DLSample| > 1 or |DLResult| > 1)throw ('Only a single dictionary for DLSample and DLResult is allowed')
endif
*
* Get the dictionary keys.
get_dict_param (DLSample, 'keys', [], SampleKeys)
if (DLResult != [])get_dict_param (DLResult, 'keys', [], ResultKeys)
endif
*
* Get image ID if it is available.
get_dict_param (DLSample, 'key_exists', 'image_id', ImageIDExists)
if (ImageIDExists)get_dict_tuple (DLSample, 'image_id', ImageID)ImageIDString := 'image ID ' + ImageIDImageIDStringBraces := '(image ID ' + ImageID + ')'ImageIDStringCapital := 'Image ID ' + ImageID
elseImageIDString := ''ImageIDStringBraces := ImageIDStringImageIDStringCapital := ImageIDString
endif
* AdditionalGreenClassNames := []
KeyIndex := 0* whl添加if*
* Check if DLDatasetInfo is valid.* whl添加
DLDatasetInfo:=DLDataInfo* Check if DLDatasetInfo contains necessary keys.ClassKeys := ['class_names', 'class_ids']get_handle_param (DLDatasetInfo, 'key_exists', ClassKeys, ClassKeysExist)if (min(ClassKeysExist) == 0)* In that case we expect that the class names and ids are never used.elseget_handle_param (DLDatasetInfo, 'keys', [], DLDatasetInfoKeys)for Index := 0 to |ClassKeys| - 1 by 1if (find_first(DLDatasetInfoKeys,ClassKeys[Index]) == -1)throw ('Key ' + ClassKeys[Index] + ' is missing in DLDatasetInfo.')endifendfor* * Get the general dataset information, if available.get_handle_tuple (DLDatasetInfo, 'class_names', ClassNames)get_handle_tuple (DLDatasetInfo, 'class_ids', ClassIDs)* * 为类定义不同的颜色* get_dl_class_colors (ClassNames, AdditionalGreenClassNames, Colors)* 函数get_dl_class_colors 替代者,开始* Define distinct colors for the classes.
NumColors := |ClassNames|
* Get distinct colors without randomness makes neighboring colors look very similar.
* We use a workaround to get deterministic colors where subsequent colors are distinguishable.
get_distinct_colors (NumColors, false, 0, 200, ColorsRainbow)tuple_inverse (ColorsRainbow, ColorsRainbow)
make_neighboring_colors_distinguishable (ColorsRainbow, Colors)
* If a class 'OK','ok', 'good' or 'GOOD' or a class specified in AdditionalGreenClassNames is present set this class to green.
* Only the first occurrence found is set to a green shade.
tuple_union (['good', 'GOOD', 'ok', 'OK'], AdditionalGreenClassNames, ClassNamesGood)
for IndexFind := 0 to |ClassNamesGood| - 1 by 1GoodIdx := find_first(ClassNames,ClassNamesGood[IndexFind])if (GoodIdx != -1 and |ClassNames| <= 8)* If number of classes is <= 8, swap color with a green color.CurrentColor := Colors[GoodIdx]GreenIdx := floor(|ClassNames| / 2.0)* Set to pure green.Colors[GoodIdx] := '#00ff00'* Write original color to a green entry.Colors[GreenIdx] := CurrentColorbreakelseif (GoodIdx != -1 and |ClassNames| > 8)* If number of classes is larger than 8, set the respective color to green.Colors[GoodIdx] := '#00ff00'breakendif
endfor
* 函数get_dl_class_colors 替代者,结束endif*
* ** Set window parameters: ***
* *
* ** Display the data: ***
*
* Display data dictionaries.
KeyIndex := 0*while (KeyIndex < |KeysForDisplay|)* * if (KeysForDisplay[KeyIndex] == 'bbox_result' or KeysForDisplay[KeyIndex] == 'ocr_detection_result')* * Result bounding boxes on image.图像上的结果边界框。get_dl_sample_image (Image, SampleKeys, DLSample, 'image')* get_dl_sample_image (ImageBatch, SampleKeys, DLSample, 'image')* * Get or open next window.训练时的图片宽高get_image_size (Image, WidthImage, HeightImage)* get_next_window (Params.font, Params.font_size, Params.display_bottom_desc, WidthImage, HeightImage, 0, Params.scale_windows, Params.threshold_width, PrevWindowCoordinates, WindowHandleDict, KeysForDisplay[KeyIndex], CurrentWindowHandle, WindowImageRatio, PrevWindowCoordinates)*原始代码,whl测试注释,训练时的压缩后图片* dev_display (Image)*whl添加,获取窗口尺寸* get_window_extents(WindowID1,Row,Column,Window_Width,Window_Height)*图片原图本身尺寸,非训练设置压缩的图片尺寸get_image_size (ImageBatch, WidthBig, HeightBig)*whl添加,比值*应该先把训练时图片的原始框点转换图片本身尺寸时的坐标就可以了imgRate:=1imgHeightBeiWidth:=1if(1)*宽度,乘以1.0转为小数,可以让除得到小数结果imgRate:=WidthBig/(WidthImage*1.0)* 高度占宽度的比值imgHeightBeiWidth:=HeightBig/(HeightImage*1.0)endif*whl 添加,显示原图片* 调整图像尺寸* zoom_image_size(ImageBatch,imgZoom,800,800*HeightBig/(WidthBig*1.0),'constant')* zoom_image_size(ImageBatch,imgZoom,800,800*HeightBig/(WidthBig*1.0),'constant')dev_clear_window()*whl 添加,显示原图片 dev_display(ImageBatch)*让窗口适应图片的尺寸,窗口跟图片一样大* dev_resize_window_fit_image (ImageBatch, 0, 0, -1, -1)* dev_re* dev_open_window_fit_image (ImageBatch, 0, 0, -1, -1, WindowID1)*dev_resize_window_fit_size (0, 0, -1, -1, -1, -1)*full_domain(ImageBatch,ImageBatch)* dev_set_window(WindowID1)* dev_set_part*whl 添加测试WindowImageRatio:=1CurrentWindowHandle:=WindowID1*目标对象分类文本* className:=DLResult.bbox_class_name*显示目标对象框 *dev_display_result_detection (DLResult, ResultKeys, Params.line_width, ClassIDs, TextConf, Colors, Params.bbox_label_color, WindowImageRatio, 'top', Params.bbox_text_color, Params.display_labels, DisplayDirectionTemp, CurrentWindowHandle, BboxClassIndex)*dev_display_result_detection (DLResult, ResultKeys, Params.line_width, ClassIDs, TextConf, Colors, Params.bbox_label_color, WindowImageRatio, 'top', Params.bbox_text_color, Params.display_labels, DisplayDirectionTemp, CurrentWindowHandle, BboxClassIndex)*目标文本显示set_display_font (WindowID1, 12, 'mono', 'false', 'false') *提取函数,显示目标对象框,识别分类文本,开始
InstanceType := ''
MaskExists := false
if (find(ResultKeys,'bbox_row1') != -1) *进这个get_dict_tuple (DLResult, 'bbox_row1', BboxRow1)get_dict_tuple (DLResult, 'bbox_col1', BboxCol1)get_dict_tuple (DLResult, 'bbox_row2', BboxRow2)get_dict_tuple (DLResult, 'bbox_col2', BboxCol2)InstanceType := 'rectangle1'*1进入,0不进入if(1) *whl 添加,乘以系数*高度BboxRow1:=BboxRow1*imgHeightBeiWidth BboxRow2:=BboxRow2*imgHeightBeiWidth*宽度BboxCol1:=BboxCol1*imgRateBboxCol2:=BboxCol2*imgRate*whl 添加,重置为1imgRate:=1endifelseif (find(ResultKeys,'bbox_phi') != -1)get_dict_tuple (DLResult, 'bbox_row', BboxRow)get_dict_tuple (DLResult, 'bbox_col', BboxCol)get_dict_tuple (DLResult, 'bbox_length1', BboxLength1)get_dict_tuple (DLResult, 'bbox_length2', BboxLength2)get_dict_tuple (DLResult, 'bbox_phi', BboxPhi)get_dict_tuple (DLResult, 'bbox_class_id', BboxClasses)InstanceType := 'rectangle2'
elsethrow ('Result bounding box data could not be found in DLResult.')
endif
if (find(ResultKeys,'mask') != -1)get_dict_object (InstanceMask, DLResult, 'mask')MaskExists := true
endif
if (InstanceType != 'rectangle1' and InstanceType != 'rectangle2' and not MaskExists)throw ('Result bounding box or mask data could not be found in DLSample.')
endif*whl注释
get_dict_tuple (DLResult, 'bbox_class_id', BboxClasses)* whl 添加,显示检测对象名称*whl添加
ShowLabels:=true
ShowDirection:=true
TextColor:='#eeeeee'TextConf:=''if (|BboxClasses| > 0)* * Get text and text size for correct positioning of result class IDs.if (ShowLabels)Text := BboxClasses + TextConfget_string_extents (CurrentWindowHandle, Text, Ascent, Descent, _, _)TextOffset := (Ascent + Descent) / WindowImageRatioendif* * Generate bounding box XLDs.if (InstanceType == 'rectangle1')tuple_gen_const (|BboxRow1|, 0.0, BboxPhi)*画目标框线,乘以 imgRategen_rectangle2_contour_xld (BboxRectangle, 0.5 * (BboxRow1 + BboxRow2), 0.5 * (BboxCol1 + BboxCol2), BboxPhi, 0.5 * (BboxCol2 - BboxCol1), 0.5 * (BboxRow2 - BboxRow1))* gen_rectangle2_contour_xld (BboxRectangle, 0.5 * (BboxRow1 + BboxRow2)*imgRate, 0.5 * (BboxCol1 + BboxCol2)*imgRate, BboxPhi, 0.5 * (BboxCol2 - BboxCol1)*imgRate, 0.5 * (BboxRow2 - BboxRow1)*imgRate)if (ShowLabels)LabelRowTop := BboxRow1LabelRowBottom := BboxRow2 - TextOffsetLabelCol := BboxCol1endifelseif (InstanceType == 'rectangle2')gen_rectangle2_contour_xld (BboxRectangle, BboxRow, BboxCol, BboxPhi, BboxLength1, BboxLength2)if (ShowLabels)LabelRowTop := BboxRow - TextOffsetLabelRowBottom := BboxRowLabelCol := BboxColendifif (ShowDirection)if (ShowDirection == -1)ArrowSizeFactorLength := 0.4ArrowSizeFactorHead := 0.2MaxLengthArrow := 20HalfLengthArrow := min2(MaxLengthArrow,BboxLength1 * ArrowSizeFactorLength)ArrowBaseRow := BboxRow - (BboxLength1 - HalfLengthArrow) * sin(BboxPhi)ArrowBaseCol := BboxCol + (BboxLength1 - HalfLengthArrow) * cos(BboxPhi)ArrowHeadRow := BboxRow - (BboxLength1 + HalfLengthArrow) * sin(BboxPhi)ArrowHeadCol := BboxCol + (BboxLength1 + HalfLengthArrow) * cos(BboxPhi)ArrowHeadSize := min2(MaxLengthArrow,min2(BboxLength1,BboxLength2)) * ArrowSizeFactorHeadelseArrowHeadSize := 20.0ArrowBaseRow := BboxRowArrowBaseCol := BboxColArrowHeadRow := BboxRow - (BboxLength1 + ArrowHeadSize) * sin(BboxPhi)ArrowHeadCol := BboxCol + (BboxLength1 + ArrowHeadSize) * cos(BboxPhi)endifgen_arrow_contour_xld (OrientationArrows, ArrowBaseRow, ArrowBaseCol, ArrowHeadRow, ArrowHeadCol, ArrowHeadSize, ArrowHeadSize)endifelseif (MaskExists)area_center (InstanceMask, _, MaskRow, MaskCol)LabelRowTop := MaskRow - TextOffsetLabelRowBottom := MaskRowLabelCol := MaskColelsethrow ('Unknown instance_type: ' + InstanceType)endif* get_contour_style (CurrentWindowHandle, ContourStyle)dev_set_contour_style ('stroke')get_line_style (CurrentWindowHandle, Style)*whl添加LineWidthBbox:=1LineWidths := [LineWidthBbox + 2,LineWidthBbox]dev_set_line_width (LineWidthBbox)* * Collect ClassIDs of the bounding boxes.tuple_gen_const (|BboxClasses|, 0, BboxClassIndices)* * Draw bounding boxes.for IndexBbox := 0 to |BboxClasses| - 1 by 1ClassID := find(ClassIDs,BboxClasses[IndexBbox])BboxClassIndices[IndexBbox] := ClassID* First draw in black to make the class-color visible.CurrentColors := ['black',Colors[ClassID]]if (MaskExists)select_obj (InstanceMask, MaskSelected, IndexBbox + 1)dev_set_draw ('fill')dev_set_color (Colors[ClassID] + '80')dev_display (MaskSelected)dev_set_draw ('margin')endiffor IndexStyle := 0 to |CurrentColors| - 1 by 1dev_set_color (CurrentColors[IndexStyle])dev_set_line_width (LineWidths[IndexStyle])if (InstanceType != '')select_obj (BboxRectangle, RectangleSelected, IndexBbox + 1)dev_display (RectangleSelected)if (InstanceType == 'rectangle2' and ShowDirection)select_obj (OrientationArrows, ArrowSelected, IndexBbox + 1)dev_display (ArrowSelected)endifendifendforendfor* * Draw text of bounding boxes.if (ShowLabels)* For better visibility the text is displayed after all bounding boxes are drawn.* Get text and text size for correct positioning of result class IDs.* Text := BboxClasses + TextConf*whl 对象文本*bbox_class_name标签,bbox_confidence置信度得分whlObjectClassName:=DLResult.bbox_class_name*四舍五入,保留10位小数tuple_string(DLResult.bbox_confidence, '.10f', StringConfidence) *截取字符串tuple_substr (StringConfidence, 0, 3, Substring)Text :=whlObjectClassName+ Substring* Select text color.if (TextColor == '')TextColorClasses := Colors[BboxClassIndices]elsetuple_gen_const (|BboxClassIndices|, TextColor, TextColorClasses)endif* Select correct position of the text.LabelRow := LabelRowTop*whl注释
* if (TextPositionRow == 'bottom')* LabelRow := LabelRowBottom* endif*whl添加,标签字体背景色BoxLabelColor:='#00000099' * BoxLabelColor:='#05E600'* Display text.显示对象标签文本 dev_disp_text (Text, 'image', LabelRow, LabelCol, TextColorClasses, ['box_color', 'shadow', 'border_radius'], [BoxLabelColor,'false', 0])endif* dev_set_contour_style (ContourStyle)set_line_style (CurrentWindowHandle, Style)
else* Do nothing if no results are present.BboxClassIndices := []
endif*显示目标对象框,识别分类文本,结束*whl 注释,不执行if代码里面的代码endif* KeyIndex := KeyIndex + 1
*endwhile * whl测试,目标框显示,结束 *whl注释* WindowHandles := WindowHandleDict.bbox_result* dev_set_window (WindowHandles[0])* set_display_font (WindowHandles[0], 16, 'mono', 'true', 'false')* whl测试* set_display_font (WindowID1, 16, 'mono', 'true', 'false')*whl注释,不显示绿色的检测文本列表* dev_disp_text (Text, 'window', 'top', 'left', TextColor, ['box_color', 'shadow'], [TextBoxColor,'false'])set_display_font (WindowID1, 16, 'mono', 'true', 'false') * dev_disp_text ('Press Run (F5) to continue', 'window', 'bottom', 'right', 'black', [], [])* 拆分字符串,图片路径 tuple_split(Batch,'\\',fileWordArr)Wordlength:=|fileWordArr|*取最后一个字符串fileShortName:=fileWordArr[Wordlength-1]*显示文件名dev_disp_text (fileShortName, 'window', 'bottom', 'left', 'magenta', [], [])*将窗口保存为本地图片文件* dump_window(WindowID1,'png','G:/机器视觉_测试项目/家具目标检测/videoImages/2')stop ()endfor
endfor
*
* Close windows used for visualization.关闭用于可视化的窗口
*dev_close_window_dict (WindowHandleDict)
*
*
set_display_font (WindowID1, 24, 'mono', 'true', 'false') dev_disp_text ('程序结束', 'window', 'bottom', 'right', 'green', ['box_color'], [ 'blue'])
本地函数 get_distinct_colors()
*
* We get distinct color-values first in HLS color-space.
* Assumes hue [0, EndColor), lightness [0, 1), saturation [0, 1).
*
* Parameter checks.
* NumColors.
if (NumColors < 1)throw ('NumColors should be at least 1')
endif
if (not is_int(NumColors))throw ('NumColors should be of type int')
endif
if (|NumColors| != 1)throw ('NumColors should have length 1')
endif
* Random.
if (Random != 0 and Random != 1)tuple_is_string (Random, IsString)if (IsString)Random := Random == 'true' or 'false'elsethrow ('Random should be either true or false')endif
endif
* StartColor.
if (|StartColor| != 1)throw ('StartColor should have length 1')
endif
if (StartColor < 0 or StartColor > 255)throw ('StartColor should be in the range [0, 255]')
endif
if (not is_int(StartColor))throw ('StartColor should be of type int')
endif
* EndColor.
if (|EndColor| != 1)throw ('EndColor should have length 1')
endif
if (EndColor < 0 or EndColor > 255)throw ('EndColor should be in the range [0, 255]')
endif
if (not is_int(EndColor))throw ('EndColor should be of type int')
endif
*
* Color generation.
if (StartColor > EndColor)EndColor := EndColor + 255
endif
if (NumColors != 1)Hue := (StartColor + int((EndColor - StartColor) * real([0:NumColors - 1]) / real(NumColors - 1))) % 255
elseHue := mean([StartColor,EndColor])
endif
if (Random)Hue := Hue[sort_index(rand(NumColors))]Lightness := int((5.0 + rand(NumColors)) * 255.0 / 10.0)Saturation := int((9.0 + rand(NumColors)) * 255.0 / 10.0)
elseLightness := int(gen_tuple_const(NumColors,0.55) * 255.0)Saturation := int(gen_tuple_const(NumColors,0.95) * 255.0)
endif
*
* Write colors to a 3-channel image in order to transform easier.
gen_image_const (HLSImageH, 'byte', 1, NumColors)
gen_image_const (HLSImageL, 'byte', 1, NumColors)
gen_image_const (HLSImageS, 'byte', 1, NumColors)
get_region_points (HLSImageH, Rows, Columns)
set_grayval (HLSImageH, Rows, Columns, Hue)
set_grayval (HLSImageL, Rows, Columns, Lightness)
set_grayval (HLSImageS, Rows, Columns, Saturation)
*
* Convert from HLS to RGB.
trans_to_rgb (HLSImageH, HLSImageL, HLSImageS, ImageR, ImageG, ImageB, 'hls')
*
* Get RGB-values and transform to Hex.
get_grayval (ImageR, Rows, Columns, Red)
get_grayval (ImageG, Rows, Columns, Green)
get_grayval (ImageB, Rows, Columns, Blue)
Colors := '#' + Red$'02x' + Green$'02x' + Blue$'02x'
return ()
*
本地函数 make_neighboring_colors_distinguishable()
*
* Shuffle the input colors in a deterministic way
* to make adjacent colors more distinguishable.
* Neighboring colors from the input are distributed to every NumChunks
* position in the output.
* Depending on the number of colors, increase NumChunks.
NumColors := |ColorsRainbow|
if (NumColors >= 8)NumChunks := 3if (NumColors >= 40)NumChunks := 6elseif (NumColors >= 20)NumChunks := 4endifColors := gen_tuple_const(NumColors,-1)* Check if the Number of Colors is dividable by NumChunks.NumLeftOver := NumColors % NumChunksColorsPerChunk := int(NumColors / NumChunks)StartIdx := 0for S := 0 to NumChunks - 1 by 1EndIdx := StartIdx + ColorsPerChunk - 1if (S < NumLeftOver)EndIdx := EndIdx + 1endifIdxsLeft := [S:NumChunks:NumColors - 1]IdxsRight := [StartIdx:EndIdx]Colors[S:NumChunks:NumColors - 1] := ColorsRainbow[StartIdx:EndIdx]StartIdx := EndIdx + 1endfor
elseColors := ColorsRainbow
endif
return ()
相关文章:
halcon机器视觉深度学习对象检测,物体检测
目录 效果图操作步骤软件版本halcon参考代码本地函数 get_distinct_colors()本地函数 make_neighboring_colors_distinguishable() 效果图 操作步骤 首先要在Deep Learning Tool工具里面把图片打上标注文本, 然后训练模型,导出模型文件 这个是模型 mod…...
go 反射 interface{} 判断类型 获取值 设置值 指针才可以设置值
内容包括 1. 用interface{}接收值 2. 判断interface{}的类型 switch 3. 打印interface{}的类型 4. 通过字符串对结构体,interface{}等进行设置值、获取值处理 示例代码 package mainimport ("fmt""log""reflect" )type Student…...
单臂路由
单臂路由(Router on a Stick)是一种网络配置方式,主要用于在单个物理接口上实现多个VLAN之间的路由。它通常用于交换机与路由器之间的连接,适用于VLAN间通信需求较小的情况。 工作原理 VLAN划分:交换机上配置多个VLAN…...
SpringBoot【实用篇】- 测试
文章目录 目标: 1.加载测试专用属性3.Web环境模拟测试2.加载测试专用配置4.数据层测试回滚5.测试用例数据设定 目标: 加载测试专用属性加载测试专用配置Web环境模拟测试数据层测试回滚测试用例数据设定 1.加载测试专用属性 我们在前面讲配置高级的…...
NutUI内网离线部署
文章目录 官网拉取源代码到本地仓库修改源代码打包构建nginx反向代理部署访问内网离线地址 在网上找了一圈没有写NutUI内网离线部署的文档,花了1天时间研究下,终于解决了。 对于有在内网离线使用的小伙伴就可以参考使用了 如果还是不会联系UP主:QQ:10927…...
【深度学习】Adam和AdamW优化器有什么区别,以及为什么Adam会被自适应学习率影响
Adam 和 AdamW 的主要区别在于 权重衰减(Weight Decay) 的实现方式,具体如下: 1. 权重衰减(Weight Decay)处理方式 Adam:采用 L2 正则化,通过在梯度更新时手动添加 weight_decay 项…...
Pytorch的F.cross_entropy交叉熵函数
参考笔记:pytorch的F.cross_entropy交叉熵函数和标签平滑函数_怎么给crossentropyloss添加标签平滑-CSDN博客 先来讲下基本的交叉熵cross_entropy,官网如下:torch.nn.functional.cross_entropy — PyTorch 1.12 documentation torch.nn.fun…...
一文讲解Redis为什么读写性能高以及I/O复用相关知识点
Redis为什么读写性能高呢? Redis 的速度⾮常快,单机的 Redis 就可以⽀撑每秒十几万的并发,性能是 MySQL 的⼏⼗倍。原因主要有⼏点: ①、基于内存的数据存储,Redis 将数据存储在内存当中,使得数据的读写操…...
[特殊字符] Elasticsearch 双剑合璧:HTTP API 与 Java API 实战整合指南
🚀 Elasticsearch 双剑合璧:HTTP API 与 Java API 实战整合指南 一、HTTP API 定义与用途 Elasticsearch 的 HTTP API 是基于 RESTful 接口设计的核心交互方式,支持通过 URL 和 JSON 数据直接操作索引、文档、集群等资源。适用于快速调试、…...
某手sig3-ios算法 Chomper黑盒调用
Chomper-iOS界的Unidbg 最近在学习中发现一个Chomper框架,Chomper 是一个模拟执行iOS可执行文件的框架,类似于安卓端大名鼎鼎的Unidbg。 这篇文章使用Chomper模拟执行某手的sig3算法,初步熟悉该框架。这里只熟悉模拟执行步骤以及一些常见的…...
蓝桥杯之阶段考核
📖 Day 7:阶段考核 - 蓝桥杯官方模拟赛(限时 4 小时) 📖 一、如何高效完成模拟赛? 模拟赛是一种接近真实竞赛的训练方式。要高效完成模拟赛,需要掌握以下策略: 1. 赛前准备 ✅ 环…...
DeepSeek掘金——VSCode 接入DeepSeek V3大模型,附使用说明
VSCode 接入DeepSeek V3大模型,附使用说明 由于近期 DeepSeek 使用人数激增,服务器压力较大,官网已 暂停充值入口 ,且接口响应也开始不稳定,建议使用第三方部署的 DeepSeek,如 硅基流动 或者使用其他模型/插件,如 豆包免费AI插件 MarsCode、阿里免费AI插件 TONGYI Lin…...
华为昇腾服务器(固件版本查询、驱动版本查询、CANN版本查询)
文章目录 1. **查看固件和驱动版本**2. **查看CANN版本**3. **其他辅助方法**注意事项 在华为昇腾服务器上查看固件、驱动和CANN版本的常用方法如下: 1. 查看固件和驱动版本 通过命令行工具 npu-smi 执行以下命令查看当前设备的固件(Firmware࿰…...
红帽7基于kickstart搭建PXE环境
Kickstart 文件是一种配置文件,用于定义 Linux 系统安装过程中的各种参数,如分区、网络配置、软件包选择等。system-config-kickstart 提供了一个图形界面,方便用户快速生成这些配置文件。 用户可以通过图形界面进行系统安装的详细配置&…...
【Python爬虫(58)】从0到1:Scrapy实战爬取大型新闻网站
【Python爬虫】专栏简介:本专栏是 Python 爬虫领域的集大成之作,共 100 章节。从 Python 基础语法、爬虫入门知识讲起,深入探讨反爬虫、多线程、分布式等进阶技术。以大量实例为支撑,覆盖网页、图片、音频等各类数据爬取ÿ…...
DeepSeek使用从入门到精通
1. DeepSeek概述 - DeepSeek是国产大模型,提供网页版和App版。因其强大功能,遭受网络攻击,但国内用户可直接使用。 2. 入门技巧 - 忘掉复杂提示词:用简洁明了的需求指令,AI能自我思考并生成优质内容 - 明确需求&#…...
【分布式数据一致性算法】Gossip协议详解
在分布式系统中,多个节点同时提供服务时,数据一致性是核心挑战。在多个节点中,若其中一个节点的数据发生了修改,其他节点的数据都要进行同步。 一种比较简单粗暴的方法就是 集中式发散消息,简单来说就是一个主节点同时…...
一、初始爬虫
1.爬虫的相关概念 1.1 什么是爬虫 网络爬虫(又被称为网页蜘蛛,网络机器人)就是模拟浏览器发送网络请求,接收请求响应,一种按照一定的规则,自动地爬取互联网信息的程序。 原则上,只要是浏览器…...
C语言番外篇(3)------------>break、continue
看到我的封面图的时候,部分读者可能认为这和编程有什么关系呢? 实际上这个三个人指的是本篇文章有三个部分组成。 在之前的博客中我们提及到了while循环和for循环,在这里面我们学习了它们的基本语法。今天我们要提及的是关于while循环和for…...
ipad连接电脑断断续续,不断弹窗的解决办法
因为ipad air 屏幕摔坏,换了一个内外屏,想用爱思检验一下屏幕真伪, 连接电脑时,断断续续,连上几秒钟然后就断开,然后又连上 然后又断开,不断地弹出信任的弹窗。 刚开始以为是数据线问题&#x…...
dockerfile构建haproxy
1. 结构目录 [rootlocalhost ~]# tree haproxy/ haproxy/ ├── dockerfile └── files├── haproxy-2.5.0.tar.gz├── haproxy.cfg├── install.sh└── start.sh1 directory, 5 files [rootlocalhost ~]# [rootlocalhost ~]# cd haproxy/ [rootlocalhost haproxy]…...
创建第一个 Maven 项目(一)
一、引言 在 Java 开发的广袤天地中,Maven 宛如一位全能的管家,发挥着举足轻重的作用。它是一个基于项目对象模型(POM)的项目管理和构建自动化工具,极大地简化了 Java 项目的开发流程。 Maven 的核心优势之一在于其强…...
深度学习pytorch之19种优化算法(optimizer)解析
提示:有谬误请指正 摘要 本博客详细介绍了多种常见的深度学习优化算法,包括经典的LBFGS 、Rprop 、Adagrad、RMSprop 、Adadelta 、ASGD 、Adamax、Adam、AdamW、NAdam、RAdam以及SparseAdam等,通过对这些算法的公式和参数说明进行详细解析…...
C#贪心算法
贪心算法:生活与代码中的 “最优选择大师” 在生活里,我们常常面临各种选择,都希望能做出最有利的决策。比如在超市大促销时,面对琳琅满目的商品,你总想用有限的预算买到价值最高的东西。贪心算法,就像是一…...
SSH无密登录配置
SSH无密登录配置 1、在用户目录下创建.ssh目录 mkdir /home/atguigu/.ssh2、在.ssh目录下生成ssh秘钥(需要切换到Hadoop集群使用的用户,再运行命令) ssh-keygen -t rsa然后敲(三个回车),就会生成两个文件…...
Rust并发编程实践:10分钟入门系统级编程
目录 学前一问:Rust为何而出现? 摘要 引言 正文解析: 一、Rust中的并发编程基础 1.1 线程 1.2 协程 二、Rust并发编程的高级特性 2.1 通道 2.2 原子操作 2.3 锁 三、实例展示:优化并发编程性能 1. 并行计算 2. 异步…...
Linux 命令大全完整版(06)
2. 系统设置命令 pwunconv 功能说明:关闭用户的投影密码。语法:pwunconv补充说明:执行 pwunconv 指令可以关闭用户投影密码,它会把密码从 shadow 文件内,重回存到 passwd 文件里。 rdate(receive date) 功能说明&a…...
VSCode 中设置 Git 忽略仅因时间戳修改导致的文件变更【使用deepseek生成的一篇文章】
在 VSCode 中设置 Git 忽略仅因时间戳修改导致的文件变更,可通过以下步骤实现: 确认是否为纯时间戳修改 首先确认文件的修改是否仅涉及时间戳,使用终端运行: git diff -- <file>若输出为空但 Git 仍提示修改,可…...
echarts找不到了?echarts社区最新地址
前言:在之前使用echarts的时候,还可以通过上边的导航栏找到echarts社区,但是如今的echarts变更之后,就找不到echarts社区了。 ✨✨✨这里是秋刀鱼不做梦的BLOG ✨✨✨想要了解更多内容可以访问我的主页秋刀鱼不做梦-CSDN博客 如今…...
Git-速查
Git 安装 Git 之后,你可以… 配置全局用户信息(推荐) 全局设置,创建本地仓库时默认分支名称为 main(你需要什么名称就该什么名称)【推荐配置为 main 】 git config --global init.defaultBranch main全…...
AxiosError: Network Error
不知怎么的,项目还在开发阶段,之前还好好的,玩儿了两天再一打开发现页面无法显示数据了,报错如下: 我以为是后端出问题了,但是后端控制台无报错,又用postman测试了一下,可以获取到数…...
ImGui 学习笔记(三)—— 隐藏主窗口窗口关闭检测
ImGui 的主窗口是平台窗口,默认是可见的,这会影响视觉效果。那么怎么隐藏 ImGui 的主窗口呢? 这很简单,但是需要针对后端做一些修改。 本文仅介绍在 glfwopengl3 和 win32dx11 两种实现上如何修改。 在 win32dx11 实现上&#…...
周末总结(2024/02/22)
工作 人际关系核心实践: 要学会随时回应别人的善意,执行时间控制在5分钟以内 坚持每天早会打招呼 遇到接不住的话题时拉低自己,抬高别人(无阴阳气息) 朋友圈点赞控制在5min以内,职场社交不要放在5min以外 职场的人际关系在面对利…...
SOME/IP--协议英文原文讲解11
前言 SOME/IP协议越来越多的用于汽车电子行业中,关于协议详细完全的中文资料却没有,所以我将结合工作经验并对照英文原版协议做一系列的文章。基本分三大块: 1. SOME/IP协议讲解 2. SOME/IP-SD协议讲解 3. python/C举例调试讲解 4.2.6 Er…...
Spring Boot 概要(官网文档解读)
Spring Boot 概述 Spring Boot 是一个高效构建 Spring 生产级应用的脚手架工具,它简化了基于 Spring 框架的开发过程。 Spring Boot 也是一个“构件组装门户”,何为构件组装门户呢?所谓的“构件组装门户”指的是一个对外提供的Web平台&#x…...
图像处理篇---图像处理中常见参数
文章目录 前言一、分贝(dB)的原理1.公式 二、峰值信噪比(PSNR, Peak Signal-to-Noise Ratio)1.用途2.公式3.示例 三、信噪比(SNR, Signal-to-Noise Ratio)1.用途2.公式3.示例 四、动态范围(Dyna…...
Win11更新系统c盘爆满处理
1.打开磁盘管理 2.右击c盘选择属性,进行磁盘管理,选择详细信息。 3.选择以前安装的文件删除即可释放c盘空间。...
C++关键字之mutable
1.介绍 在C中,mutable是一个关键字,用于修饰类的成员变量。它的主要作用是允许在常量成员函数或常量对象中修改被标记为mutable的成员变量。通常情况下,常量成员函数不能修改类的成员变量,但有些情况下,某些成员变量的…...
vue3 采用xlsx库实现本地上传excel文件,前端解析为Json数据
需求:本地上传excel 文件,但需要对excel 文件的内容进行解析,然后展示出来 1. 安装依赖 首先,确保安装了 xlsx 库: bash复制 npm install xlsx 2. 创建 Vue 组件 创建一个 Vue 组件(如 ExcelUpload.v…...
【Linux系统】—— 冯诺依曼体系结构与操作系统初理解
【Linux系统】—— 冯诺依曼体系结构与操作系统初理解 1 冯诺依曼体系结构1.1 基本概念理解1.2 CPU只和内存打交道1.3 为什么冯诺依曼是这种结构1.4 理解数据流动 2 操作系统2.1 什么是操作系统2.2 设计OS的目的2.3 操作系统小知识点2.4 如何理解"管理"2.5 系统调用和…...
易语言模拟真人鼠标轨迹算法 - 防止游戏检测
一.简介 鼠标轨迹算法是一种模拟人类鼠标操作的程序,它能够模拟出自然而真实的鼠标移动路径。 鼠标轨迹算法的底层实现采用C/C语言,原因在于C/C提供了高性能的执行能力和直接访问操作系统底层资源的能力。 鼠标轨迹算法具有以下优势: 模拟…...
PHP旅游门票预订系统小程序源码
🌍 旅游门票预订系统:一站式畅游新体验,开启您的梦幻旅程 🌟 一款基于ThinkPHPUniapp精心雕琢的旅游门票预订系统,正翘首以待,为您揭开便捷、高效、全面的旅游预订新篇章!它超越了传统预订平台…...
侯捷 C++ 课程学习笔记:内存管理的每一层面
目录 一、C 应用程序的内存管理架构 二、C 内存原语 三、内存管理的实际应用 四、学习心得 一、C 应用程序的内存管理架构 C 应用程序的内存管理架构可以分为多个层次,从应用程序到操作系统 API,每一层都提供了不同的内存管理功能。 架构图…...
Python开发Django面试题及参考答案
目录 Django 的请求生命周期是怎样的? Django 的 MTV 架构中的各个组件分别是什么? Django 的 URL 路由是如何工作的? Django 的视图函数和视图类有什么区别? Django 的模板系统是如何渲染 HTML 的? Django 的 ORM 是如何工作的? Django 的中间件是什么?它的作用是…...
前端js进阶,ES6语法,包详细
进阶ES6 作用域的概念加深对js理解 let、const申明的变量,在花括号中会生成块作用域,而var就不会生成块作用域 作用域链本质上就是底层的变量查找机制 作用域链查找的规则是:优先查找当前作用域先把的变量,再依次逐级找父级作用域直到全局…...
【三十四周】文献阅读:DeepPose: 通过深度神经网络实现人类姿态估计
目录 摘要AbstractDeepPose: 通过深度神经网络实现人类姿态估计研究背景创新点方法论归一化网络结构级联细化流程 代码实践局限性实验结果总结 摘要 人体姿态估计旨在通过图像定位人体关节,是计算机视觉领域的核心问题之一。传统方法多基于局部检测与图模型&#x…...
将 Vue 项目打包后部署到 Spring Boot 项目中的全面指南
将 Vue 项目打包后部署到 Spring Boot 项目中的全面指南 在现代 Web 开发中,前后端分离架构已经成为主流。然而,在某些场景下,我们可能需要将前端项目(如 Vue)与后端项目(如 Spring Boot)集成部…...
Linux 权限系统和软件安装(二):深入理解 Linux 权限系统
在 Linux 的世界里,权限系统犹如一位忠诚的卫士,严密守护着系统中的文件与目录,确保只有具备相应权限的用户才能进行操作。与其他一些操作系统不同,Linux 并不依据文件后缀名来标识文件的操作权限,而是构建了一套独特且…...
计算机网络常考大题
运输层的主要功能 运输层为应用进程之间提供端到端的逻辑通信。 运输层还要对收到的报文进行差错检测。 运输层需要有两种不同的运输协议,即面向连接的 TCP 和无连接的 UDP 传输控制协议 TCP 概述 TCP 是面向连接的运输层协议。 每一条 TCP 连接只能有两个端点…...
百度首页上线 DeepSeek 入口,免费使用
大家好,我是小悟。 百度首页正式上线了 DeepSeek 入口,这一重磅消息瞬间在技术圈掀起了惊涛骇浪,各大平台都被刷爆了屏。 百度这次可太给力了,PC 端开放仅 1 小时,就有超千万人涌入体验。这速度,简直比火…...