二维和三维联合进行圆孔空间定位

0.任务描述

  • 对空间圆孔进行三维空间的定位,方便后续的抓取或装配
  • 流程:使用二维图与opencv霍夫圆检测进行二维上的定位,再从深度图上查询深度信息,结合相机内参计算出相机坐标系下圆孔的三维坐标信息,并在点云上进行标注

1.二维定位与圆周点获取

  • 使用opencv霍夫圆检测,下段程序可以鼠标拖动来调整参数,检测到的圆心坐标和半径以x,y,r的顺序打印出来
  • 在图片相同路径下生成同名的txt文档,一共四行,分别是圆心x坐标,圆心y坐标,半径,圆周上若干点的坐标(格式x,y;x,y;)
import cv2
import numpy as np
from math import sin,cos


# 更新阈值
def updateThreshold(x):

    # 缩放参数
    resize_scale = cv2.getTrackbarPos('resize_scale', 'param_select')
    
    # 裁减的坐标参数
    x1 = cv2.getTrackbarPos('x1', 'param_select')
    x2 = cv2.getTrackbarPos('x2', 'param_select')
    y1 = cv2.getTrackbarPos('y1', 'param_select')
    y2 = cv2.getTrackbarPos('y2', 'param_select')
    
    # 滤波参数
    blur_type = cv2.getTrackbarPos('blur_type', 'param_select')
    
    # 霍夫圆检测参数
    dp = cv2.getTrackbarPos('dp', 'param_select')
    minDist = cv2.getTrackbarPos('minDist', 'param_select')
    param1 = cv2.getTrackbarPos('param1', 'param_select')
    param2 = cv2.getTrackbarPos('param2', 'param_select')
    minRadius = cv2.getTrackbarPos('minRadius', 'param_select')
    maxRadius = cv2.getTrackbarPos('maxRadius', 'param_select')
    
    #在圆周上画出点
    num = cv2.getTrackbarPos('num', 'param_select')
    
    # 缩放操作
    img_resize = cv2.resize(img,None,fx=resize_scale*0.1,fy=resize_scale*0.1) 
    cv2.imshow('resize', img_resize)
    
    # 裁减操作
    img_crop = img_resize[y1:y2, x1:x2]
    cv2.imshow('crop', img_crop)
    
    # 灰度化和滤波
    img_gray = cv2.cvtColor(img_crop, cv2.COLOR_BGR2GRAY)  
    img_blur = cv2.blur(img_gray, (2 * blur_type + 1, 2 * blur_type + 1))  
    cv2.imshow('img_blur', img_blur)
    
    # 检测主函数
    circles = cv2.HoughCircles(img_blur, cv2.HOUGH_GRADIENT, dp=dp, minDist=minDist, param1=param1, param2=param2, minRadius=minRadius, maxRadius=maxRadius)
    
    # 用于循环显示更新
    pro_result = np.zeros_like(img_crop)
    result = np.zeros_like(img)
    points_datas = datas+'.txt'
    if circles is not None:
        points_datas = open(points_datas,'w')
        circles = np.uint16(np.around(circles))
        print('circles numbers:', circles.shape[1])
        print('draw on image!') 
        # 用于更新
        pro_result[:] = img_crop
        result[:] = img
        for i in circles[0, :]:
            
            # 在预处理的图片上标记
            cv2.circle(pro_result, (i[0], i[1]), i[2], (0, 255, 0), 2)
            cv2.circle(pro_result, (i[0], i[1]), 2, (0, 0, 255), 3)
            
            # 计算坐标和半径
            result_x = (i[0] + x1)/resize_scale/0.1
            result_y = (i[1] + y1)/resize_scale/0.1
            result_r = i[2]/resize_scale/0.1
            points_datas.write(str(int(result_x))+'\n')
            points_datas.write(str(int(result_y))+'\n')
            points_datas.write(str(int(result_r))+'\n')
            
            #计算圆周上的点
            for i in range(num):
                points_x,points_y = int(result_r * cos(360/num*i) + result_x), int(result_r * sin(360/num*i) + result_y)
                cv2.circle(result, (int(points_x), int(points_y)), 2, (0, 0, 255), 10)
                # print(i,points_x,points_y)
                points_datas.write(str(int(points_x))+',' + str(int(points_y)) + ';')
            points_datas.write('\n')

            # 在原图片上标记
            cv2.circle(result, (int(result_x), int(result_y)), int(result_r), (0, 255, 8), 1)
            cv2.circle(result, (int(result_x), int(result_y)), 2, (0, 0, 255), 10)
            
            # 输出坐标和半径
            print(int(result_x), int(result_y), result_r)
        points_datas.close()
    else:
        print("No circles detected.")
    
    cv2.imshow('pro_result', pro_result)
    cv2.imshow('result', result)

if __name__ == "__main__":
    
    # 载入图片
    datas = 'detectimages/example/depth_image_00000'
    img = cv2.imread(datas + '.png')


    # 创建显示框
    cv2.namedWindow('param_select', flags= cv2.WINDOW_NORMAL | cv2.WINDOW_FREERATIO)
    
    cv2.namedWindow('resize', flags= cv2.WINDOW_NORMAL | cv2.WINDOW_FREERATIO)
    cv2.namedWindow('crop', flags= cv2.WINDOW_NORMAL | cv2.WINDOW_FREERATIO)
    cv2.namedWindow('img_blur', flags= cv2.WINDOW_NORMAL | cv2.WINDOW_FREERATIO)
    cv2.namedWindow('pro_result', flags= cv2.WINDOW_NORMAL | cv2.WINDOW_FREERATIO)
    cv2.namedWindow('result', flags= cv2.WINDOW_NORMAL | cv2.WINDOW_FREERATIO)

    # 创建滑动条 当滑动条有变化时调用updateThreshold函数
    cv2.createTrackbar('resize_scale','param_select',1,10,updateThreshold)
    
    cv2.createTrackbar('x1','param_select',0,3072,updateThreshold)
    cv2.createTrackbar('x2','param_select',3072,3072,updateThreshold)
    cv2.createTrackbar('y1','param_select',0,2048,updateThreshold)
    cv2.createTrackbar('y2','param_select',2048,2048,updateThreshold)

    cv2.createTrackbar('blur_type','param_select',3,5,updateThreshold)
    
    cv2.createTrackbar('dp','param_select',1,15,updateThreshold)
    cv2.createTrackbar('minDist','param_select',40,255,updateThreshold)
    cv2.createTrackbar('param1','param_select',70,255,updateThreshold)
    cv2.createTrackbar('param2','param_select',23,255,updateThreshold)
    cv2.createTrackbar('minRadius','param_select',10,255,updateThreshold)
    cv2.createTrackbar('maxRadius','param_select',30,255,updateThreshold)
    cv2.createTrackbar('num','param_select',1,360,updateThreshold)


    # 循环更新显示 空格退出
    while cv2.waitKey(0) != ord(' '):
        continue
    # 关闭所有窗口
    cv2.destroyAllWindows()

在这里插入图片描述

2.查询深度信息

  • 常用的深度图格式为png和tiff

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/299470.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

自定义View之重写onMeasure

一、重写onMeasure()来修改已有的View的尺寸 步骤: 重写 onMeasure(),并调用 super.onMeasure() 触发原先的测量用 getMeasuredWidth() 和 getMeasuredHeight() 取到之前测得的尺寸,利用这两个尺寸来计算出最终尺寸使用 setMeasuredDimensio…

[通俗易懂]c语言中指针变量和数值之间的关系

一、指针变量的定义 在C语言中,指针变量是一种特殊类型的变量,它存储的是另一个变量的内存地址。指针变量可以用来间接访问和操作内存中的其他变量。指针变量的定义如下: 数据类型 *指针变量名;其中,数据类型可以是任…

SQL优化:执行计划

前面我们讲述了使用索引或分区表来进行存储层次的优化,也讲述了通过条件提升进行结果集的优化。这边文章我们来学习一下其中的细节,即查看数据库是怎么一步一步把数据拿给我们的。也就是执行计划。 语法 explain sql语句 练习 首先,我们来玩下简单的 explain select * …

HUAWEI WATCH 系列 eSIM 全新开通指南来了

HUAWEI WATCH 系列手表提供了eSIM硬件能力,致力为用户提供更便捷、高效的通信体验。但eSIM 业务是由运营商管理并提供服务的,当前运营商eSIM业务集中全面恢复,电信已经全面恢复,移动大部分省份已经全面放开和多号App开通方式&…

20240107移远的4G模块EC20在Firefly的AIO-3399J开发板的Android11下调通能上网

20240107移远的4G模块EC20在Firefly的AIO-3399J开发板的Android11下调通能上网 2024/1/7 11:17 开发板:Firefly的AIO-3399J【RK3399】SDK:rk3399-android-11-r20211216.tar.xz【Android11】 Android11.0.tar.bz2.aa【ToyBrick】 Android11.0.tar.bz2.ab …

Docker mysql 主从复制

目录 介绍:为什么需要进行mysql的主从复制 主从复制原理: ✨主从环境搭建 主从一般面试问题: 介绍:为什么需要进行mysql的主从复制 在实际的生产中,为了解决Mysql的单点故障已经提高MySQL的整体服务性能&#xff…

如何恢复Mac误删文件?

方法1. 使用撤消命令 当你在 Mac 上删除了错误的文件并立即注意到你的错误时,你可以使用撤消命令立即恢复它。顾名思义,此命令会反转上次完成的操作,并且有多种方法可以调用它。如果你已经采取了其他操作或退出了用于删除文件的应用程序&…

算法与数据结构之数组(Java)

目录 1、数组的定义 2、线性结构与非线性结构 3、数组的表现形式 3.1 一维数组 3.2 多维数组 4、重要特性:随机访问 5、ArrayList和数组 6、堆内存和栈内存 7、数组的增删查改 7.1 插入数据 7.2 删除一个数据 7.3 修改数组 7.4 查找数据 8、总结 什么…

蓝桥杯基础知识2 全排列 next_permutation(), prev_permutation()

蓝桥杯基础知识2 全排列 next_permutation()&#xff0c; prev_permutation() #include<bits/stdc.h> using namespace std;int a[10];int main(){for(int i 1; i < 4; i)a[i] i; //4*3*2*1 24bool tag true;while(tag){for(int i1; i < 4; i)cout << a[…

Fiddler工具 — 8.会话列表(Session List)

1、会话列表说明 Fiddler抓取到的每条HTTP请求&#xff08;每一条称为一个session&#xff09;。 主要包含了请求的ID编号、状态码、协议、主机名、URL、内容类型、body大小、进程信息、自定义备注等信息。如下图&#xff1a; 说明&#xff1a; 名称含义#抓取HTTP Request的顺…

电脑如何屏幕录制?轻松录制高清视频

在当今信息化的时代&#xff0c;电脑已经成为工作和生活的重要工具。无论是在进行演示、教学还是记录重要操作步骤时&#xff0c;屏幕录制都是非常有用的。可是电脑如何屏幕录制呢&#xff1f;本篇文章将介绍三种常见的电脑屏幕录制方法&#xff0c;通过学习这些方法&#xff0…

[C#]使用DlibDotNet人脸检测人脸68特征点识别人脸5特征点识别人脸对齐人脸比对FaceMesh

【官方框架地址】 https://github.com/takuya-takeuchi/DlibDotNet 【算法介绍】 DlibDotNet是一个开源的.NET库&#xff0c;用于实现机器学习和计算机视觉应用。它基于C库dlib&#xff0c;通过C/CLI封装了dlib的所有功能&#xff0c;为.NET开发者提供了简单易用的API。以下是…

力扣刷题记录(29)LeetCode:695、1020、130

695. 岛屿的最大面积 这道题和计算岛屿周长类似&#xff0c;在这里dfs的功能就是由一块陆地出发&#xff0c;找出这块陆地所在的岛屿并返回岛屿面积。 class Solution { public:int dfs(vector<vector<int>>& grid,int i,int j){if(i<0||i>grid.size())…

微信小程序 获取地址信息(uniapp)

参考API地址&#xff1a;微信小程序JavaScript SDK | 腾讯位置服务 <script> // 引入SDK核心类&#xff0c;js文件根据自己业务&#xff0c;位置可自行放置var QQMapWX require(../../js/uploadImg/qqmap-wx-jssdk.js);export default {data(){return{qqmapsdk:}},onL…

【Spring Cloud】组件概念详解

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是Java方文山&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的专栏《Spring Cloud》。&#x1f3af;&#x1f3af; &am…

Hive精选10道面试题

1.Hive内部表和外部表的区别&#xff1f; 内部表的数据由Hive管理&#xff0c;外部表的数据不由Hive管理。 在Hive中删除内部表后&#xff0c;不仅会删除元数据还会删除存储数据&#xff0c; 在Hive中删除外部表后&#xff0c;只会删除元数据但不会删除存储数据。 内部表一旦…

odoo17 | 用户界面的基本交互

前言 现在我们已经创建了我们的新模型及其 相应的访问权限&#xff0c;是时候了 与用户界面交互。 在本章结束时&#xff0c;我们将创建几个菜单以访问默认列表 和窗体视图。 数据文件 &#xff08;XML&#xff09; Odoo在很大程度上是数据驱动的&#xff0c;因此模块定义的…

pytoch安装

pytoch安装 1. 准备工作1.1 需要提前安装的软件 2. 安装pyTorch我遇到的问题 3. 显卡测试4. CPU与GPU切换方法4.1 创建张量4.2 第一种切换方法4.3 第二种切换方法 1. 准备工作 1.1 需要提前安装的软件 Anaconda 史上最全最详细的Anaconda安装教程CUDA CUDA安装教程&#xff0…

Python笔记06-文件操作

文章目录 文件的编码文件读取文件写入文件追加 文件的编码 编码技术即&#xff1a;翻译的规则&#xff0c;记录了如何将内容翻译成二进制&#xff0c;以及如何将二进制翻译回可识别内容。算机中有许多可用编码&#xff1a;UTF-8、GBK、Big5等 不同的编码&#xff0c;将内容翻译…

其他排序(基数排序,希尔排序和桶排序)(数据结构课设篇3,python版)(排序综合)

本篇博客主要详细讲解一下其他排序&#xff08;基数排序&#xff0c;希尔排序和桶排序&#xff09;也是排序综合系列里最后一篇博客。第一篇博客讲解的是LowB三人组&#xff08;冒泡排序&#xff0c;插入排序&#xff0c;选择排序&#xff09;&#xff08;数据结构课设篇1&…