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