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 ()

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

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

相關文章

9.PG數據庫層權限管理(pg系列課程)第2遍

一、PostgreSQL數據庫屬主 Postgres中的數據庫屬主屬于創建者&#xff0c;只要有createdb的權限就可以創建數據庫&#xff0c;數據庫屬主不一定擁有存放在該數據庫中其它用戶創建的對象的訪問權限。數據庫在創建后&#xff0c;允許public角色連接&#xff0c;即允許任何人連接…

2.19學習(php文件后綴)

misc buu-后門查殺 下載附件&#xff0c;我們用火絨安全掃一下然后點擊詳情進入該文件所在文件夾&#xff0c;再用記事本打開該文件&#xff0c;搜索flag無果&#xff0c;再試試pass&#xff08;由題目中的密碼聯系到pass&#xff0c;password&#xff0c;key等&#xff09;&a…

PMBOK第7版整體架構全面詳解

1. 引言 7月1日對于項目管理從業者和研究者而言&#xff0c;是個非凡意義的一個時間&#xff0c;這一天&#xff0c;翹首以待的《 項 目管理知識體系指南 》&#xff08;PMBOK&#xff09;第七版終于發布了。 總體而言&#xff0c;PMBOK第七版集百家之所長&#xff0c;成一…

C++:類與對象,定義類和構造函數

#define _CRT_SECURE_NO_WARNINGS 1 #include <iostream> using namespace std; //如何讓定義一個類 // 封裝 // 1、將數據和方法定義到一起。 // 2、把想給你看的數據給你看&#xff0c;不想給你看的封裝起來。 通過訪問限定符來實現 class Stack { public: //1.成…

nginx 部署前端vue項目

?? 主頁&#xff1a; ?? 感謝各位大佬 點贊?? 收藏 留言?? 加關注! ?? 收錄于專欄&#xff1a;前端工程師 文章目錄 一、??什么是nginx&#xff1f;二、??nginx 部署前端vue項目步驟 2.1 ??安裝nginx 2.1.1 ??windows環境安裝2.1.2 ??linux環境安裝 2.2 …

藍橋杯備考策略

備賽策略 (1-2周):基礎算法數據結構 (3-5周):動態規劃/貪心圖論 (6-8周):全真模擬查漏補缺 階段1:基礎鞏固(第1-2周) **目標:**掌握基礎數據結構和必考算法&#xff0c;熟悉藍橋杯題型。 學習內容: 數據結構:數組、字符串、棧、隊列、哈希表、二叉樹(遍歷與基本操作)。 基礎…

tmux和vim的基本操作

Tmux Tmux 的核心功能 多窗口和多面板&#xff1a; 在一個終端中創建多個窗口&#xff08;Windows&#xff09;&#xff0c;每個窗口可以運行不同的任務。 在每個窗口中&#xff0c;可以進一步分割成多個面板&#xff08;Panes&#xff09;&#xff0c;實現分屏操作。 會話…

Lineageos 22.1(Android 15) 開機向導制作

一、前言 開機向導原理其實就是將特定的category的Activity加入ComponentResolver&#xff0c;如下 <category android:name"android.intent.category.SETUP_WIZARD"/>然后我們開機啟動的時候&#xff0c;FallbackHome結束&#xff0c;然后啟動Launcher的時候…

【二分搜索 C/C++】洛谷 P1873 EKO / 砍樹

2025 - 02 - 19 - 第 55 篇 Author: 鄭龍浩 / 仟濹(CSND) 【二分搜索】 文章目錄 洛谷 P1873 EKO / 砍樹題目描述輸入格式輸出格式輸入輸出樣例 #1輸入 #1輸出 #1 輸入輸出樣例 #2輸入 #2輸出 #2 說明/提示題目中的部分變量思路代碼 洛谷 P1873 EKO / 砍樹 題目描述 伐木工人…

DeepSeek系列模型發展:從LLM到V3、R1的技術突破與優化各階段的重要論文匯總(附下載地址)

DeepSeek 系列模型從最初的 LLM 版本發展到最新的 V3 和 R1 版本&#xff0c;在架構設計、訓練效率和推理能力方面不斷取得進步。以下是各版本按時間倒序的詳細信息&#xff1a; 1. DeepSeek-R1 發布時間&#xff1a;2025年1月 論文標題&#xff1a;DeepSeek-R1: Incentivizi…

HTTP SSE 實現

參考&#xff1a; SSE協議 SSE技術詳解&#xff1a;使用 HTTP 做服務端數據推送應用的技術 一句概擴 SSE可理解為&#xff1a;服務端和客戶端建立連接之后雙方均保持連接&#xff0c;但僅支持服務端向客戶端推送數據。推送完畢之后關閉連接&#xff0c;無狀態行。 下面是基于…

推薦一款AI大模型托管平臺-OpenWebUI

推薦一款AI大模型托管平臺-OpenWebUI 1. OpenWebUI 1. OpenWebUI什么? 官網地址&#xff1a;https://openwebui.com/ GitHub地址&#xff1a; https://github.com/open-webui/open-webui Open WebUI 是一個可擴展、功能豐富且用戶友好的自托管 AI 平臺&#xff0c;旨在完全離…

js中常用方法整理

數據類型 typeOf()Number&#xff08;&#xff09;parseInt()parseFloat()- * / %檢測數據類型轉換為數字轉換為整數類型轉換為浮點類型非加法的數字運算toString()Boolean()String()轉換為字符串&#xff0c;不能轉換undefined/null字符串拼接轉換為布爾類型轉換為字符串、所有…

java練習(33)

ps:題目來自力扣 最強回文子串 給你一個字符串 s&#xff0c;找到 s 中最長的 回文 子串。 class Solution {public String longestPalindrome(String s) {if (s null || s.length() < 1) {return "";}int start 0, end 0;for (int i 0; i < s.length();…

本地部署DeepSeek大模型

環境&#xff1a;nuc工控機器 x86架構 ubuntu20.04 1、瀏覽器打開Download Ollama on Linux&#xff0c;復制命令。 2.打開終端&#xff0c;輸入命令。 curl -fsSL https://ollama.com/install.sh | sh 等待安裝&#xff0c;安裝完成后&#xff0c;終端輸入 ollama&#xff…

Nginx 常用命令和部署詳解及案例示范

一、Nginx常用命令 1.1 啟動 Nginx 要啟動 Nginx 服務&#xff0c;可以使用以下命令&#xff1a; sudo systemctl start nginx1.2 停止 Nginx 如果需要停止 Nginx 服務&#xff0c;可以使用以下命令&#xff1a; sudo systemctl stop nginx1.3 重啟 Nginx 在修改了 Nginx…

2025鴻蒙開發面試題匯總——通俗易懂

問題和通俗易懂的答案&#xff0c;覆蓋鴻蒙開發的核心知識點和實際場景&#xff0c;方便面試時快速評估候選人能力&#xff1a; 一、基礎概念&#xff08;必問&#xff09; 鴻蒙和安卓最大的區別是什么&#xff1f;舉個實際例子。 答案&#xff1a;鴻蒙是“分布式操作系統”&am…

Kotlin 優雅的接口實現

1. 日常遇到的冗余的接口方法實現 日常開發中&#xff0c;經常會要實現接口&#xff0c;但是很多場景中&#xff0c;只需要用到其中一兩個方法&#xff0c;例如 ActivityLifecycleCallbacks&#xff0c;它有很多個接口需要實現&#xff0c;但是很多時候我們只需要用到其中的一…

Java List 自定義對象排序 Java 8 及以上版本使用 Stream API

從 Java 8 開始&#xff0c;你可以使用 Stream API 對 List 進行排序&#xff0c;這種方式更加簡潔和靈活。 以下是一個示例代碼&#xff1a; import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.stream.Collectors;// 自定…

【Spring詳解一】Spring整體架構和環境搭建

一、Spring整體架構和環境搭建 1.1 Spring的整體架構 Spring框架是一個分層架構&#xff0c;包含一系列功能要素&#xff0c;被分為大約20個模塊 Spring核心容器&#xff1a;包含Core、Bean、Context、Expression Language模塊 Core &#xff1a;其他組件的基本核心&#xff…