1、生成一個箭頭輪廓算子
gen_arrow_contour_xld( : Arrow : Row1, Column1, Row2, Column2, HeadLength, HeadWidth : )
該算子一般配合
area_center (region, Area, Row, Column)
orientation_region (region, Phi)
算子使用,生成一個箭頭輪廓。
2、速度最快的濾波和邊緣檢測算子
*二項濾波
binomial_filter (ImageSrc, ImageSrc, MaskSize, MaskSize)
*利用sobel算子檢測邊
sobel_amp (ImageSrc, EdgeAmplitude, 'sum_abs', 3)
*通過fast_threshold全局門檻值快速門檻值化處理
fast_threshold (EdgeAmplitude, Region, LowThreshold, 255, 300)
3、實作圖像灰階歸一化
*轉化為Real類型
convert_image_type (Image, ImageConverted, 'real')
*将圖像灰階縮放至0-1
scale_image (ImageConverted, ImageScaled, 1.0/255, 0)
4、求兩個輪廓之間的最短距離
gen_circle (Circle, 200, 200, 100.5)
gen_circle (Circle1, 188, 190, 70)
gen_contour_region_xld (Circle, Contours1, 'border')
gen_contour_region_xld (Circle1, Contours2, 'border')
*找出兩個圓形輪廓之間的最小距離
distance_cc_min_points (Contours1, Contours2, 'fast_point_to_segment', DistanceMin1, Row1, Column1, Row2, Column2)
dev_set_color ('green')
gen_region_line (RegionLines, Row1, Column1, Row2, Column2)
disp_message (200000, '最小距離:' + DistanceMin1, 'image', 0, 0, 'green', 'false')
另一個功能是可以得到兩個輪廓最小距離的兩個點的坐标。不然很多算子都可以,distance_pc、distance_cc都可以
gen_circle (Circle, 200, 200, 100.5)
gen_circle (Circle1, 188, 190, 70)
gen_contour_region_xld (Circle, Contours1, 'border')
gen_contour_region_xld (Circle1, Contours2, 'border')
get_contour_xld (Contours1, Row, Col)
get_contour_xld (Contours2, Row1, Col1)
distance_pc (Contours2, Row, Col, DistanceMin, _)
tuple_find (DistanceMin, min(DistanceMin), Indices)
distance_pc (Contours1, Row1, Col1, DistanceMin1, _)
tuple_find (DistanceMin1, min(DistanceMin1), Indices1)
gen_contour_polygon_xld (Contour, [Row[Indices],Row1[Indices1]], [Col[Indices],Col1[Indices1]])
使用OpenCV來求輪廓點最短距離
# https://mp.weixin.qq.com/s/p1oenefEH1A7-PJoLX8wMw
# -*- coding: cp936 -*-
import numpy as np
import math
import cv2
def cal_pt_distance(pt1, pt2):
dist = math.sqrt(pow(pt1[0]-pt2[0],2) + pow(pt1[1]-pt2[1],2))
return dist
font = cv2.FONT_HERSHEY_SIMPLEX
img = cv2.imread('test.jpg')
cv2.imshow('src',img)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (3,3), 0)
ret,thresh = cv2.threshold(gray, 150, 255, cv2.THRESH_BINARY)
contours,hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
#thresh,contours,hierarchy = cv2.findContours(thresh, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
flag = False
minDist = 10000
minPt0 = (0,0)
minPt1 = (0,0)
for i in range(0,len(contours[1])):#周遊所有輪廓
pt = tuple(contours[1][i][0])
#print(pt)
min_dis = 10000
min_pt = (0,0)
#distance = cv2.pointPolygonTest(contours[1], pt, False)
for j in range(0,len(contours[0])):
pt2 = tuple(contours[0][j][0])
distance = cal_pt_distance(pt, pt2)
#print(distance)
if distance < min_dis:
min_dis = distance
min_pt = pt2
min_point = pt
if min_dis < minDist:
minDist = min_dis
minPt0 = min_point
minPt1 = min_pt
temp = img.copy()
cv2.drawContours(img,contours,1,(255,255,0),1)
cv2.line(temp,pt,min_pt,(0,255,0),2,cv2.LINE_AA)
cv2.circle(temp, pt,5,(255,0,255),-1, cv2.LINE_AA)
cv2.circle(temp, min_pt,5,(0,255,255),-1, cv2.LINE_AA)
cv2.imshow("img",temp)
if cv2.waitKey(1)&0xFF ==27: #按下Esc鍵退出
flag = True
break
if flag:
break
cv2.line(img,minPt0,minPt1,(0,255,0),2,cv2.LINE_AA)
cv2.circle(img, minPt0,3,(255,0,255),-1, cv2.LINE_AA)
cv2.circle(img, minPt1,3,(0,255,255),-1, cv2.LINE_AA)
cv2.putText(img,("min_dist=%0.2f"%minDist), (minPt1[0],minPt1[1]+15), font, 0.7, (0,255,0), 2)
cv2.imshow('result', img)
cv2.imwrite('result.png',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
5、實作類似OpenCV中給圖像邊緣加邊框(copyMakeBorder)的算法
try
get_image_size (src, Width, Height)
gen_image_const (dst, 'byte', Width+border_x*2, Height+border_y*2)
paint_region (dst, dst, dst, 255, 'fill')
get_region_points (src, Rows, Columns)
get_grayval (src, Rows, Columns, Grayval)
Rows := Rows+border_y
Columns := Columns+border_x
set_grayval (dst, Rows, Columns, Grayval)
catch (Exception)
endtry
或者更簡潔的方式:
get_image_size (src, Width, Height)
tile_images_offset (src, dst, border_y, border_x, 0, 0, Height+border_y, Width+border_x, Width+border_x*2, Height+border_y*2)
6、SVM在工業分類
*http://www.ihalcon.com/read-11275-1.html
try
dev_close_window ()
dev_update_off ()
dev_set_draw ('margin')
dev_set_colored (12)
* 缺陷的名稱
DefectNames := ['win_scratch','mura','win_point']
* 缺陷顔色
DefectColors := ['green','yellow','blue']
*
* 準備和生成分類訓練器
create_class_svm (11, 'linear', 0.01, 0.02, |DefectNames|, 'one-versus-one', 'normalization', 10, SVMHandle)
dev_open_window (0, 0, 512, 512, 'black', WindowHandle)
*
* 循環訓練面劃缺陷
*
list_image_files ('C:/Users/Administrator/Desktop/缺陷分類/面劃', 'default', [], ScratchImageFiles)
for I := 0 to |ScratchImageFiles|-1 by 1
* 在訓練圖檔中分割出缺陷
read_image (Image, ScratchImageFiles[I])
rgb1_to_gray (Image, GrayImage)
intensity (Image, GrayImage, Mean, Deviation)
threshold (GrayImage, Region, 0, Mean-Deviation)
connection (Region, ConnectedRegions)
select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 50, 99999)
fill_up (SelectedRegions, ScratchDefects)
* 顯示分割結果
dev_display (Image)
dev_set_color ('white')
dev_display (ScratchDefects)
disp_message (WindowHandle, 'Collecting ' + DefectNames[0] + ' samples', 'window', 12, 12, 'black', 'true')
*
* 計算出缺陷的特征,并将其添加到分類器訓練結構中
*
count_obj (ScratchDefects, Number)
for Index := 0 to Number-1 by 1
select_obj (ScratchDefects, ObjectSelected, Index+1)
calculate_features (ObjectSelected, Image, Features)
add_sample_class_svm (SVMHandle, Features, 0)
endfor
*
dev_set_color (DefectColors[0])
dev_display (ScratchDefects)
endfor
stop ()
*
* 循環訓練面劃缺陷
*
list_image_files ('C:/Users/Administrator/Desktop/缺陷分類/視窗髒污', 'default', [], MuraImageFiles)
for I := 0 to |MuraImageFiles|-1 by 1
* 在訓練圖檔中分割出缺陷
read_image (Image, MuraImageFiles[I])
segment_defects (Image, MuraDefects)
* 顯示分割結果
dev_display (Image)
dev_set_color ('white')
dev_display (MuraDefects)
disp_message (WindowHandle, 'Collecting ' + DefectNames[1] + ' samples', 'window', 12, 12, 'black', 'true')
*
* 計算出缺陷的特征,并将其存儲在分類器訓練結構中
*
count_obj (MuraDefects, Number)
for Index := 0 to Number-1 by 1
select_obj (MuraDefects, ObjectSelected, Index+1)
calculate_features (ObjectSelected, Image, Features)
add_sample_class_svm (SVMHandle, Features, 1)
endfor
*
* Visualize processed pills
dev_set_color (DefectColors[1])
dev_display (MuraDefects)
endfor
stop ()
*
* 循環訓練凸點缺陷
*
list_image_files ('C:/Users/Administrator/Desktop/缺陷分類/凸點', 'default', [], PointImageFiles)
for I := 0 to |PointImageFiles|-1 by 1
* 在訓練圖檔中分割出缺陷
read_image (Image, PointImageFiles[I])
segment_defects (Image, PointDefects)
* 顯示分割結果
dev_display (Image)
dev_set_color ('white')
dev_display (PointDefects)
disp_message (WindowHandle, 'Collecting ' + DefectNames[2] + ' samples', 'window', 12, 12, 'black', 'true')
*
* 計算出缺陷的特征,并将其存儲在分類器訓練結構中
*
count_obj (PointDefects, Number)
for Index := 0 to Number-1 by 1
select_obj (PointDefects, ObjectSelected, Index+1)
calculate_features (ObjectSelected, Image, Features)
add_sample_class_svm (SVMHandle, Features, 2)
endfor
*
* Visualize processed pills
dev_set_color (DefectColors[2])
dev_display (PointDefects)
endfor
stop ()
*
* 訓練svm分類器
dev_clear_window ()
disp_message (WindowHandle, 'Training...', 'window', 12, 12, 'black', 'true')
stop ()
count_seconds (Start)
train_class_svm (SVMHandle, 0.0001, 'default')
count_seconds (End)
Time := End-Start
disp_message (WindowHandle, 'Training completed! Run Time: ' + Time$'0.2' + 'S', 'window', 12, 12, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
*
* 用自動選擇最合适的特征的分類器去分類測試的圖檔
*
list_image_files ('F:/17001白玻蓋闆/20180803-100piece/100片樣品', 'default', [], ImageFiles)
for Index := 0 to |ImageFiles|-1 by 1
dev_close_window ()
*視窗劃傷缺陷
gen_empty_obj (WinScratchDefects)
*視窗髒污缺陷
gen_empty_obj (WinMuraDefects)
*視窗凸點缺陷
gen_empty_obj (WinPointDefects)
* 在測試的圖檔中分割出缺陷
* read_image (Image, ImageFiles[Index])
read_image (Image, 'F:/17001白玻蓋闆/20180803-100piece/100片樣品/18-B.png')
get_image_size (Image, Width, Height)
dev_open_window (0, 0, Width/20, Height/20, 'black', WindowHandle1)
dev_display (Image)
inspect_all_defect (Image, Defects1)
*
* 計算出每個缺陷的特征,再用上面得到的分類器去分類這些缺陷
*
count_seconds (Start)
DefectsIDs := []
count_obj (Defects1, NDefectss)
for P := 1 to NDefectss by 1
select_obj (Defects1, DefectSelected,P)
calculate_features (DefectSelected, Image, Features)
classify_class_svm (SVMHandle, Features, 1, Class)
* Display results
DefectsIDs := [DefectsIDs,Class]
dev_set_color (DefectColors[Class])
dev_display (DefectSelected)
area_center (DefectSelected, Area, Row, Column)
disp_message (WindowHandle, Class+1, 'image', Row, Column - 10, DefectColors[Class], 'false')
if (Class == 0)
concat_obj (WinScratchDefects, DefectSelected, WinScratchDefects)
endif
if (Class == 1)
concat_obj (WinMuraDefects, DefectSelected, WinMuraDefects)
endif
if (Class == 2)
concat_obj (WinPointDefects, DefectSelected, WinPointDefects)
endif
endfor
count_seconds (End)
Time := End-Start
* wait_seconds (2)
dev_display (Image)
dev_set_color ('green')
dev_display (WinScratchDefects)
dev_set_color ('yellow')
dev_display (WinMuraDefects)
dev_set_color ('blue')
dev_display (WinPointDefects)
disp_message (WindowHandle, 'Classification Time: ' + Time$'.2' + ' S', 'window', 0, 0, 'black', 'true')
stop ()
endfor
* 清空記憶體
clear_class_svm (SVMHandle)
catch (Exception)
endtry