实战 | 电感元件定位--Halcon与OpenCV实现详解(附源码)

2022-04-06 20:45:36 浏览数 (1)

导读

本文给大家分享一个电感元件定位实例,并附Halcon和OpenCV实现步骤和代码。

背景介绍

本实例来源于EmguCV学员交流群,已经同意使用图片做演示。

如上图所示线圈电感元件,目标是定位元件中心位置然后用机械手抓取,精度要求不是很高,但由于线圈纹路影响,匹配效果不太好,这里演示用Blob分析的方法来定位。最终效果如下:

实现步骤与演示

【1】转为灰度图 二值化:

【2】孔洞填充(可参考以下历史文章):

OpenCV技巧 | 二值图孔洞填充方法与实现(附源码)

【3】形态学开运算(可参考以下历史文章):

OpenCV形态学处理使用技巧与应用演示

【4】计算中心和角度并绘制:

Halcon实现源码与其他图片测试:

代码语言:javascript复制
dev_get_window (WindowHandle)
read_image (Image, './imgs/1 (5).jpg')
rgb1_to_gray (Image, GrayImage)
threshold (GrayImage, Regions, 0, 230)
fill_up (Regions, RegionFillUp)

dev_set_color ('blue')
dev_set_draw ('margin')
dev_set_line_width (2)
opening_rectangle1 (RegionFillUp, RegionOpening, 70, 70)
dev_display (Image)
select_shape (RegionOpening, SelectedRegions, 'area', 'and', 200000, 500000)

orientation_region (SelectedRegions, Phi)
area_center (SelectedRegions, Area, Row, Column)
dev_set_line_width (3)
dev_set_draw ('margin')
Length := 400
dev_set_color ('red')
dev_set_line_width (2)
disp_arrow (WindowHandle, Row, Column, Row - Length * sin(Phi), Column   Length * cos(Phi), 4)
disp_message (WindowHandle, deg(Phi)$'3.1f'   ' deg', 'image', Row, Column - 20, 'green', 'false')
dev_update_window ('on')

OpenCV实现步骤与测试:

【1】二值化:

代码语言:javascript复制
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
 _,thres = cv2.threshold(gray,220,255,cv2.cv2.THRESH_BINARY_INV)

【2】孔洞填充:

代码语言:javascript复制
def fill_up(thres):
  img_out = thres.copy()
  contours,hierarchy = cv2.findContours(thres, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
  cv2.drawContours(img_out,contours,-1,(255,255,255),-1) 
  return img_out

【3】形态学开运算:

代码语言:javascript复制
k1=np.ones((70,70), np.uint8)
opening = cv2.morphologyEx(filled, cv2.MORPH_OPEN, k1)

【4】计算中心和角度并标示:

代码语言:javascript复制
contours,hierarchy = cv2.findContours(opening, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
for cnt in contours:
  area = cv2.contourArea(cnt)
  if(area>20000):
    cv2.drawContours(result,cnt,-1,(255,0,0),2)
    M = cv2.moments(cnt)
    cx = int(M['m10']/M['m00'])
    cy = int(M['m01']/M['m00'])#轮廓重心
    center = (cx,cy)
    
    rect = cv2.minAreaRect(cnt)
    angle = rect[2]
    print(angle)
    box = cv2.boxPoints(rect)
    box = np.int0(box)
    img = cv2.drawContours(result,[box],0,(0,0,255),1)
    angle = get_angle(box,center)
    print(angle)
    ptEnd = get_end_point(center,angle,cnt)
    #cv2.circle(result,ptEnd,5,(255,0,255),-1)
    cv2.arrowedLine(result,center,ptEnd,(0, 255, 0),thickness=3, line_type=cv2.LINE_4,
                    shift=0, tipLength=0.08)
    cv2.circle(result,center,5,(0,0,255),-1)
    pt_text = (center[0],center[1]-15)
    strAngle = '%0.2fdeg'%(-angle 180)
    cv2.putText(result,strAngle,pt_text,0,0.7,(0,255,0),2)

---计算角度方式有差异,所以得到的角度不同---

0 人点赞