Python+OpenCV实现单个圆形孔和针检测
作者:天人合一peng 发布时间:2023-05-04 10:38:11
标签:Python,OpenCV,圆形,检测
如果中间红色区域是针则可以用下面的代码检测,其阈值和斑点检测的参数根据图像像素值做相应修改
检测的主要思路是先通过找到外面的大圆,再通过圆心定位出一个ROI区域,在ROI区域中检测中心的检测对象
import os
import cv2
import numpy as np
import math
# 检测针脚位置
def needelCenter_detect(img):
params = cv2.SimpleBlobDetector_Params()
# Setup SimpleBlobDetector parameters.
# print('params')
# print(params)
# print(type(params))
# Filter by Area.
params.filterByArea = True
params.minArea = 100
params.maxArea = 10e3
params.minDistBetweenBlobs = 50
# params.filterByColor = True
params.filterByConvexity = False
# tweak these as you see fit
# Filter by Circularity
params.filterByCircularity = False
params.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.01
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Detect blobs.
minThreshValue = 110
_, gray = cv2.threshold(gray, minThreshValue, 255, cv2.THRESH_BINARY)
# gray = cv2.resize(gray, dsize=None, fx=2, fy=2, interpolation=cv2.INTER_LINEAR)
# plt.imshow(gray)
# cv2.imshow("gray",gray)
# 找到距离原点(0,0)最近和最远的点
detector = cv2.SimpleBlobDetector_create(params)
keypoints = detector.detect(gray)
# print(len(keypoints))
# print(keypoints[0].pt[0])
# 如果这儿没检测到可能会出错
if len(keypoints) == 0:
print("没有检测到针角坐标,可能需要调整针角斑点检测参数")
return keypoints
else:
print(len(keypoints))
im_with_keypoints = cv2.drawKeypoints(gray, keypoints, np.array([]), (255, 0, 0),
cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
# if keypoints is not None:
color_img = cv2.cvtColor(im_with_keypoints, cv2.COLOR_BGR2RGB)
# 画出圆的圆心
cv2.circle(color_img, (int(keypoints[0].pt[0]), int(keypoints[0].pt[1])), 5, (0, 255, 0), -1)
cv2.imshow("color_img",color_img)
# cv2.waitKey()
return keypoints
# 检测连接器圆形位置
def circle_detect(image):
# 灰度化
circle_img = image.copy()
gray = cv2.cvtColor(circle_img, cv2.COLOR_BGR2GRAY)
# 输出图像大小,方便根据图像大小调节minRadius和maxRadius
# print(image.shape)
# 进行中值滤波
img = cv2.medianBlur(gray, 3)
# 针角圆心坐标
out_x = 0
out_y = 0
# 霍夫变换圆检测
circles = cv2.HoughCircles(img, cv2.HOUGH_GRADIENT, 1, 10e10, param1=100, param2=30, minRadius=10, maxRadius=100)
# 如果没检测到会报错
# 这种判断方式过于简单
if circles is None:
print("没有检测到连接器外圆")
else:
for circle in circles[0]:
# 圆的基本信息
# print(circle[2])
# 坐标行列-圆心坐标
out_x = int(circle[0])
out_y = int(circle[1])
# 半径
r = int(circle[2])
# 在原图用指定颜色标记出圆的边界
cv2.circle(circle_img, (out_x, out_y), r, (0, 0, 255), 2)
# # 画出圆的圆心
cv2.circle(circle_img, (out_x, out_y), 3, (0, 255, 255), -1)
# 记录外圆坐标
out_xpoint = out_x
out_ypoint = out_y
# 只框出单个针角的位置区域
step_center = 30
step_rect = 60
out_x -= step_center
out_y -= step_center
needleRect = image[out_y: out_y + step_rect, out_x: out_x + step_rect]
# cv2.imshow("needleRect", needleRect)
# 根据检测到的圆形连接器中心找针角位置
centerPoint = needelCenter_detect(needleRect)
if len(centerPoint) == 0:
print("调整位置")
else:
# 将针角的坐标原还至原图
in_x = int(centerPoint[0].pt[0])
in_y = int(centerPoint[0].pt[1])
in_x += out_x
in_y += out_y
# 画出针角的圆心
cv2.circle(circle_img, (in_x, in_y), 3, (0, 255, 0), -1)
# 计算两者的距离
# 假设通过标定其一个像素代表0.0056mm
DPI = 0.00568
dis = math.sqrt(math.pow(out_xpoint - in_x,2) + math.pow(out_ypoint - in_y,2))
print("两者相互之间的距离为(mm):", dis*DPI)
cv2.imshow("image",circle_img)
cv2.waitKey(1)
if __name__ == "__main__":
# # 测试0 如果是小图 需要将检测程序中的cv2.waitKey(1)修改为cv2.waitKey()不然看到图片
# image = cv2.imread("images/CircleLinker/CLinker01.jpg")
# # cv2.imshow("show",image)
# # cv2.waitKey()
# roi = image
# circle_detect(roi)
# 测试1 从原图中换到连接器位置
image = cv2.imread("SingleImages/src/single.jpg")
# cv2.imshow("show",image)
# cv2.waitKey()
# 如何准确找到圆形连接器 ---》用yolo训练后能准备找到
roi = image[1800:2300, 1800:2300 ]
# cv2.imshow("show",roi)
# cv2.waitKey()
circle_detect(roi)
# # 测试2 如果是小图 需要将检测程序中的cv2.waitKey(1)修改为cv2.waitKey()不然看到图片
# image = cv2.imread("SingleImages/single04.jpg")
# # cv2.imshow("show",image)
# # cv2.waitKey()
# roi = image
# circle_detect(roi)
# # 测试3 检测文件夹下所有图片
# path = r"D:\BUFFER\Pycharm\ZhenJiaoDect\SingleImages"
# for filename in os.listdir(path): # listdir的参数是文件夹的路径
# filenames = path + '\\' + filename
# # print(filenames)
# img_orig = cv2.imread(filenames, 1)
# print(filenames)
#
# if img_orig is None:
# print("Warning: No Pictures")
# else:
# circle_detect(img_orig)
# # # 测试4 打开相机测试
# # 需要将检测程序中的cv2.waitKey()修改为cv2.waitKey(1)
# # 否则看到不视频实时检测结果
# capture = cv2.VideoCapture(0)
#
# while (True):
# # 获取一帧
# ret, frame = capture.read()
# circle_detect(frame)
#
# # cv2.imshow('frame', frame)
#
# if cv2.waitKey(1) == ord('q'):
# break
来源:https://blog.csdn.net/moonlightpeng/article/details/127569671


猜你喜欢
- mysql_result定义和用法mysql_result() 函数返回结果集中一个字段的值。mysql_result() 返回 MySQL
- 前言大家好,这次写作的目的是为了加深对数据可视化pyecharts的认识,也想和大家分享一下。如果下面文章中有错误的地方还请指正,哈哈哈!!
- 一、网络爬虫网络爬虫又被称为网络蜘蛛(🕷️),我们可以把互联网想象成一个蜘蛛网,每一个网站都是一个节点,我们可以使用一只蜘蛛去各个网页抓取我
- PHP bin2hex() 函数实例把 "Hello World!" 转换为十六进制值:<?php $str =
- 什么是JSON http://www.json.org/json-zh.htmlJSON(Javascript Object Notatio
- 近期Github开源了一款基于Python开发、名为Textshot的截图工具,刚开源不到半个月已经500+Star。这两天抽空看了一下Te
- 为什么程序员都喜欢黑php?如果php经常被人黑,反而是好事!世界上只有两种语言: 没人用的和经常被人喷的。不管你喷也好,黑也好,骂也好,都
- 代码如下:<%@ Language=VBScript %> <% Dim 
- 一般学习java和部署项目都是在本地部署,但是生产环境一般都是在linux环境下,部署和安装环境都是在控制台下进行操作的,没有windows
- 今天在做sql Server 2005的实验的时候碰到的问题,问题描述很清楚,怀疑是我以前给计算机修改了名称而导致的.可以用select @
- 项目地址这个项目很神奇,直接将node.js项目打包成windows可以直接执行的exe文件(也支持FreeBSD、linux、macos、
- 说明:原来安装的python为64位,故安装的pyinstaller和打包后的exe都为64位。而64位的exe文件在32位的win7操作系
- 前文已述,因为需要测试mysql的主从配置方案,所以要安装多个mysql。这次是在ubuntu kylin 14.10上安装多个mysql
- python修改大数据文件时,如果全加载到内存中,可能会导致内存溢出。因此可借用如下方法,将分件分段读取修改。with open('
- osql简单用法:用来将本地脚本执行,适合sql脚本比较大点的情况,执行起来比较方便osql -S serverIP -U sa -P 12
- 本文实例讲述了Python wxPython库使用wx.ListBox创建列表框。分享给大家供大家参考,具体如下:如何创建一个列表框?列表框
- 动态规划(Dynamic Programming,DP)是一种常用的算法思想,通常用于解决具有重叠子问题和最优子结构性质的问题。动态规划算法
- 什么是瀑布图?瀑布图用表达两个数值之间的变化过程,过程值为正的时候,向上加,过程值为负的时候向下减[1]。今天分享在Python中绘制瀑布图
- 先上需要用到的全部代码片段(截取) MenuControl.prototype.boxDisplay = false;//是否显示图层选择菜
- 本文实例讲述了PHP获取二叉树镜像的方法。分享给大家供大家参考,具体如下:问题操作给定的二叉树,将其变换为源二叉树的镜像。解决思路翻转二叉树