检测多个圆和圆中圆的检测02

# coding:utf-8
import math
import cv2
import numpy as np
import os# 检测针脚位置
def needelCenter_detect(img):params = cv2.SimpleBlobDetector_Params()# Setup SimpleBlobDetector parameters.# print('params')# print(params)# print(type(params))# Filter by Area.params.filterByArea = Trueparams.minArea = 100params.maxArea = 10e3params.minDistBetweenBlobs = 50# params.filterByColor = Trueparams.filterByConvexity = False# tweak these as you see fit# Filter by Circularityparams.filterByCircularity = Falseparams.minCircularity = 0.2# params.blobColor = 0# # # Filter by Convexity# params.filterByConvexity = True# params.minConvexity = 0.87# Filter by Inertia# params.filterByInertia = True# params.filterByInertia = False# params.minInertiaRatio = 0.01gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# Detect blobs.minThreshValue = 100_, gray = cv2.threshold(gray, minThreshValue, 255, cv2.THRESH_BINARY)erosion_size = 1# element = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (2 * erosion_size + 1, 2 * erosion_size + 1),#                                     (erosion_size, erosion_size))element = cv2.getStructuringElement(cv2.MORPH_ERODE, (2 * erosion_size + 1, 2 * erosion_size + 1),(erosion_size, erosion_size))dilate_gray = cv2.dilate(gray, element, 1)# cv2.namedWindow("gray", 2)# cv2.imshow("gray",dilate_gray)# cv2.waitKey()detector = cv2.SimpleBlobDetector_create(params)keypoints = detector.detect(dilate_gray)# print(len(keypoints))# print(keypoints[0].pt[0])# 如果这儿没检测到可能会出错if len(keypoints) == 0:print("没有检测到针角坐标,可能需要调整针角斑点检测参数")print(keypoints)return keypointselse:print("检测到孔的数量", len(keypoints))# im_with_keypoints = cv2.drawKeypoints(img, keypoints, np.array([]), (255, 0, 0),#                                       cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)## color_img = cv2.cvtColor(im_with_keypoints, cv2.COLOR_BGR2RGB)# 画出圆的圆心# for kp in keypoints:#     cv2.circle(img, (int(kp.pt[0]), int(kp.pt[1])), 3, (0, 0, 255), -1)## cv2.namedWindow("color_img", 2)# cv2.imshow("color_img",img)# # cv2.waitKey()return keypoints# 检测外部区域针或孔的位置
def out_circle_detect(rect_hole_info, src):# 灰度化circle_img = rect_hole_infogray = cv2.cvtColor(circle_img, cv2.COLOR_HSV2RGB)gray = cv2.cvtColor(gray, cv2.COLOR_RGB2GRAY)# 输出图像大小,方便根据图像大小调节minRadius和maxRadius# print(image.shape)# 进行中值滤波img = cv2.medianBlur(gray, 3)erosion_size = 3# element = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (2 * erosion_size + 1, 2 * erosion_size + 1),#                                     (erosion_size, erosion_size))element = cv2.getStructuringElement(cv2.MORPH_ERODE, (2 * erosion_size + 1, 2 * erosion_size + 1),(erosion_size, erosion_size))dilate_gray = cv2.dilate(img, element, 1)# cv2.namedWindow("dilate_gray", 2)# cv2.imshow("dilate_gray", dilate_gray)# cv2.waitKey()# 针角圆心坐标out_x, out_y, r = 0, 0, 0# 霍夫变换检测最大圆circles = cv2.HoughCircles(dilate_gray, cv2.HOUGH_GRADIENT, 1, 1000, param1=100, param2=30, minRadius=500, maxRadius=1000)# 如果没检测到会报错# 这种判断方式过于简单if circles is None:print("没有检测到连接器外圆")return 0, 0, 0else:for circle in circles[0]:# 圆的基本信息# print(circle[2])# 坐标行列-圆心坐标out_x = int(circle[0])out_y = int(circle[1])# 将检测到的坐标保存# 半径r = int(circle[2])# print(r)# # # # 在原图用指定颜色标记出圆的边界# cv2.circle(circle_img, (out_x, out_y), r, (0, 0, 255), 2)# # # 画出圆的圆心# cv2.circle(circle_img, (out_x, out_y), 5, (0, 0, 255), -1)## cv2.namedWindow("circle_imgs", 2)# cv2.imshow("circle_imgs", circle_img)# cv2.waitKey()return out_x, out_y, r# 检测内部区域针或孔的位置
def inner_circle_detect(rect_hole_info, src):# 灰度化circle_img = rect_hole_infogray = cv2.cvtColor(circle_img, cv2.COLOR_HSV2RGB)gray = cv2.cvtColor(gray, cv2.COLOR_RGB2GRAY)# 输出图像大小,方便根据图像大小调节minRadius和maxRadius# print(image.shape)# 进行中值滤波img = cv2.medianBlur(gray, 3)erosion_size = 3element = cv2.getStructuringElement(cv2.MORPH_ERODE, (2 * erosion_size + 1, 2 * erosion_size + 1),(erosion_size, erosion_size))dilate_gray = cv2.dilate(img, element, 1)# cv2.namedWindow("dilate_gray", 2)# cv2.imshow("dilate_gray", dilate_gray)# cv2.waitKey()# 针角圆心坐标out_x_p = []out_y_p = []rudis = []# 霍夫变换检测最大圆circles = cv2.HoughCircles(dilate_gray, cv2.HOUGH_GRADIENT, 1, 100, param1=100, param2=30, minRadius=20, maxRadius=100)# 如果没检测到则返回if circles is None:print("没有检测到连接器外圆")return out_x_p, out_y_pelse:for circle in circles[0]:# 圆的基本信息# print(circle[2])# 坐标行列-圆心坐标out_x = int(circle[0])out_y = int(circle[1])# 将检测到的坐标保存out_x_p.append(out_x)out_y_p.append(out_y)# 半径r = int(circle[2])rudis.append(r)# print(r)# # # 在原图用指定颜色标记出圆的边界#     cv2.circle(circle_img, (out_x, out_y), r, (0, 0, 255), 2)#     # # 画出圆的圆心#     cv2.circle(circle_img, (out_x, out_y), 5, (0, 0, 255), -1)## cv2.namedWindow("circle_img", 2)# cv2.imshow("circle_img",circle_img)# cv2.waitKey()# 记录外圆坐标out_xpoints = out_x_p.copy()out_ypoints = out_y_p.copy()out_rudis = rudis.copy()# print("out_xpoints",out_xpoints)# print("out_ypoints",out_ypoints)# 只框出单个针角的位置区域step_center = 25step_rect = 50# 遍历所有的孔的位置# 记录孔的位置in_x_p = []in_y_p = []for i in range(0, len(out_xpoints)):out_x_begin = out_xpoints[i] - step_centerout_y_begin = out_ypoints[i] - step_centerneedleRect = circle_img[out_y_begin: out_y_begin + step_rect, out_x_begin: out_x_begin + step_rect]# cv2.namedWindow("needleRect", 2)# cv2.imshow("needleRect", needleRect)# cv2.waitKey()# 根据检测到的圆形连接器中心找针角位置centerPoint = needelCenter_detect(needleRect)# print(len(centerPoint))if len(centerPoint) == 0:out_x_p.remove(out_xpoints[i])out_y_p.remove(out_ypoints[i])rudis.remove(out_rudis[i])print("调整位置")else:for cp in centerPoint:# 将针角的坐标原还至原图in_x = int(cp.pt[0])in_y = int(cp.pt[1])in_x += out_x_beginin_y += out_y_beginin_x_p.append(in_x)in_y_p.append(in_y)# # # 画出中心孔的圆心#     cv2.circle(circle_img, (in_x, in_y), 4, (0, 255, 0), -1)#     # 画出外孔的圆心#     cv2.circle(circle_img, (out_xpoints[i], out_ypoints[i]), 4, (0, 0, 255), -1)# # 计算两者的距离#     # 假设通过标定其一个像素代表0.0056mm#     DPI = 0.0198#     dis = math.sqrt(math.pow(out_xpoints[i] - in_x,2) + math.pow(out_ypoints[i] - in_y,2))#     print("两者相互之间的距离为(mm):", dis*DPI)# cv2.namedWindow("image", 2)# cv2.imshow("image",circle_img)# cv2.waitKey()return in_x_p,in_y_pdef j599_4_holes_dectWX(imagePath, templatePath, DPI, tolerance):# templatePath需要用户手动框获取ROIimg = cv2.imread(imagePath)img_roi = cv2.imread(templatePath)if img_roi is None and img is None:print("no image")# HSV二值化img_roi = cv2.medianBlur(img_roi, 5)  # 中值滤波outx, outy, outR = out_circle_detect(img_roi, img)# print(outx, outy, outR )inx, iny = inner_circle_detect(img_roi, img)if len(inx) == 0 or outx == 0:print("没检测到位置")return "没检测到对象", -1else:# 在图中绘制检测到的外圆# cv2.circle(img_roi, (outx, outy), outR, (0, 0, 255), 3)is_ok = []real_dis = []for j in range(0, len(inx)):dis = math.sqrt(math.pow(outx - inx[j], 2) + math.pow(outy - iny[j], 2))dis *= DPIreal_dis.append(dis)# print(np.mean(real_dis))mean_dis = np.mean(real_dis)for k in range(0, len(inx)):if real_dis[k] < mean_dis + tolerance:# cv2.circle(img_roi, (inx[k], iny[k]), 8, (0, 255, 0), -1)# print("没有插针歪斜,产品合格")is_ok.append(1)else:cv2.circle(img_roi, (inx[k], iny[k]), 6, (0, 0, 255), -1)# print("有插针歪斜,不合格")is_ok.append(0)cv2.namedWindow("image", 2)cv2.imshow("image",img_roi)cv2.waitKey()isExists = os.path.exists("./runs/J599/")if not isExists:os.makedirs("./runs/J599/")cv2.imwrite("./runs/J599/result.jpg", img_roi)if 0 in is_ok:print("有插针歪斜,不合格")return "有插针歪斜,不合格"else:print("没有插针歪斜,产品合格")return "没有插针歪斜,产品合格"if __name__ == "__main__":DPI = 0.0103tolerance = 0.5reslut = j599_4_holes_dectWX("images/Final/E_0_8.jpg","J599-4holes_template.jpg", DPI, tolerance)print(reslut)
#
#     # # # 4holes
#     img = cv2.imread("images/Final/E_0_8.jpg", 1)
#     # img_roi = img[973:2027, 1713:2751]
#     # img_roi = img[852:2224, 1515:2940]
#     img_roi = img[842:2234, 1480:2950]
#     cv2.imwrite("J599-4holes_template.jpg",img_roi)
#
#     # cv2.namedWindow("img_roi",2)
#     # cv2.imshow("img_roi", img_roi)
#     # cv2.waitKey()


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部