导读
本文给大家分享一个电感元件定位实例,并附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)
---计算角度方式有差异,所以得到的角度不同---