Pvnet(一)结构

   没有配置好cpp cu的代码,因此没有调试,但是把大致的框架给学习了一下,在这里做一下记录,以后配置后了进行调试。目前顺着是自洽的,理解可能有错误,如果发现请大家指出。

1.demo.py的结构

1)提取目标对象的分割特征和每一像素点对应的方向。

      在这里面net就是Resnet18_8s,使用Resnet18_8s提取出来了seg_pred, vertex_pred,其中seg_pred表示分割出来的像素, vertex_pred表示每个分割出来的像素点的方向(理想情况下为指向真值特征/像素点的方向)。

     在NetWrapper中计算loss_seg。smooth_l1_loss计算方向损失,compute_precision_recall计算精度。

     主要是seg_pred和vertex_pred。

2)投票生成特征点(2d特征点)

   主要是这个函数,EvalWrapper中调用了ransac_voting_layer_v3来生成特征点。传入的就是seg_pred和vertex_pred。生成的是conner_pred就是生成的特征点。

3)使用pnp计算位姿。(2d-3d特征点对应)


def demo():net = Resnet18_8s(ver_dim=vote_num * 2, seg_dim=2)net = NetWrapper(net).cuda()net = DataParallel(net)optimizer = optim.Adam(net.parameters(), lr=train_cfg['lr'])model_dir = os.path.join(cfg.MODEL_DIR, "cat_demo")load_model(net.module.net, optimizer, model_dir, -1)data, points_3d, bb8_3d = read_data()image, mask, vertex, vertex_weights, pose, corner_target = [d.unsqueeze(0).cuda() for d in data]seg_pred, vertex_pred, loss_seg, loss_vertex, precision, recall = net(image, mask, vertex, vertex_weights)# visualize_mask(mask)# visualize_vertex(vertex, vertex_weights)# visualize_hypothesis(image, seg_pred, vertex_pred, corner_target)# visualize_voting_ellipse(image, seg_pred, vertex_pred, corner_target)eval_net = DataParallel(EvalWrapper().cuda())corner_pred = eval_net(seg_pred, vertex_pred).cpu().detach().numpy()[0]camera_matrix = np.array([[572.4114, 0., 325.2611],[0., 573.57043, 242.04899],[0., 0., 1.]])pose_pred = pnp(points_3d, corner_pred, camera_matrix)projector = Projector()bb8_2d_pred = projector.project(bb8_3d, pose_pred, 'linemod')bb8_2d_gt = projector.project(bb8_3d, pose[0].detach().cpu().numpy(), 'linemod')image = imagenet_to_uint8(image.detach().cpu().numpy())[0]visualize_bounding_box(image[None, ...], bb8_2d_pred[None, None, ...], bb8_2d_gt[None, None, ...])

2.ransac_voting_layer_v3

1)做一些预处理。

2)cur_hyp_pts = ransac_voting.generate_hypothesis(direct, coords, idxs)  # [hn,vn,2]

      direct就是方向,coords就是像素坐标。idx就是表示要参与计算假设点的索引。cur_hyp_pts就是根据idx中的i*2,2*i+1索引,对应的coords和direct,也就是每一个点就有一个点位置和一个方向,计算交叉点就得到了cur_hpy_pts。这个可以看cu文件,容易看懂。

3)ransac_voting.voting_for_hypothesis(direct, coords, cur_hyp_pts, cur_inlier, inlier_thresh)  # [hn,vn,tn]

    就是点到假设点之间方向与  点的方向 之间的 夹角,如果夹角满足阈值,则认为是内点。这个可以去看cu文件,感觉cu文件很好理解。

4)all_win_pts = torch.matmul(b_inv(ATA), torch.unsqueeze(ATb, 2))

    这个也比较好理解,比如对于第k个特征点,有m个点和对应的m个方向对该特征点进行投票,这时候就可以使用如下公式:

                             normal*(coords - featurePoint) = 0;

变成

             normal.t()*normal = ATA          normal.t()*[ normal*coords]表示的是ATB

求解的就是特征点位置。

看这几行代码:

       normal = torch.zeros_like(direct)   # [tn,vn,2]
        normal[:, :, 0] = direct[:, :, 1]
        normal[:, :, 1] = -direct[:, :, 0]

法向就是表示的是与点方向垂直的 方向。

      normal = normal*torch.unsqueeze(all_inlier, 2)     这个表示的是normal乘上的是一个1或者0的之时数组或者矩阵,就是表示该点和方向是否给 该特征点投票。或者可以理解为该像素点点和该像素点对应的方向 是否是 该特征点的内点。


def ransac_voting_layer_v3(mask, vertex, round_hyp_num, inlier_thresh=0.999, confidence=0.99, max_iter=20,min_num=5, max_num=30000):''':param mask:      [b,h,w]:param vertex:    [b,h,w,vn,2]:param round_hyp_num::param inlier_thresh::return: [b,vn,2]'''b, h, w, vn, _ = vertex.shapebatch_win_pts = []for bi in range(b):hyp_num = 0cur_mask = (mask[bi]).byte()foreground_num = torch.sum(cur_mask)# if too few points, just skip itif foreground_num < min_num:win_pts = torch.zeros([1, vn, 2], dtype=torch.float32, device=mask.device)batch_win_pts.append(win_pts)  # [1,vn,2]continue# if too many inliers, we randomly down sample itif foreground_num > max_num:selection = torch.zeros(cur_mask.shape, dtype=torch.float32, device=mask.device).uniform_(0, 1)selected_mask = (selection < (max_num / foreground_num.float())).byte()cur_mask *= selected_maskcoords = torch.nonzero(cur_mask).float()  # [tn,2]coords = coords[:, [1, 0]]direct = vertex[bi].masked_select(torch.unsqueeze(torch.unsqueeze(cur_mask, 2), 3))  # [tn,vn,2]direct = direct.view([coords.shape[0], vn, 2])tn = coords.shape[0]idxs = torch.zeros([round_hyp_num, vn, 2], dtype=torch.int32, device=mask.device).random_(0, direct.shape[0])all_win_ratio = torch.zeros([vn], dtype=torch.float32, device=mask.device)all_win_pts = torch.zeros([vn, 2], dtype=torch.float32, device=mask.device)cur_iter = 0while True:# generate hypothesiscur_hyp_pts = ransac_voting.generate_hypothesis(direct, coords, idxs)  # [hn,vn,2]# voting for hypothesiscur_inlier = torch.zeros([round_hyp_num, vn, tn], dtype=torch.uint8, device=mask.device)ransac_voting.voting_for_hypothesis(direct, coords, cur_hyp_pts, cur_inlier, inlier_thresh)  # [hn,vn,tn]# find maxcur_inlier_counts = torch.sum(cur_inlier, 2)                   # [hn,vn]cur_win_counts, cur_win_idx = torch.max(cur_inlier_counts, 0)  # [vn]cur_win_pts = cur_hyp_pts[cur_win_idx, torch.arange(vn)]cur_win_ratio = cur_win_counts.float() / tn# update best pointlarger_mask = all_win_ratio < cur_win_ratioall_win_pts[larger_mask, :] = cur_win_pts[larger_mask, :]all_win_ratio[larger_mask] = cur_win_ratio[larger_mask]# check confidencehyp_num += round_hyp_numcur_iter += 1cur_min_ratio = torch.min(all_win_ratio)if (1 - (1 - cur_min_ratio ** 2) ** hyp_num) > confidence or cur_iter > max_iter:break# compute mean intersection againnormal = torch.zeros_like(direct)   # [tn,vn,2]normal[:, :, 0] = direct[:, :, 1]normal[:, :, 1] = -direct[:, :, 0]all_inlier = torch.zeros([1, vn, tn], dtype=torch.uint8, device=mask.device)all_win_pts = torch.unsqueeze(all_win_pts, 0)  # [1,vn,2]ransac_voting.voting_for_hypothesis(direct, coords, all_win_pts, all_inlier, inlier_thresh)  # [1,vn,tn]# coords [tn,2] normal [vn,tn,2]all_inlier = torch.squeeze(all_inlier.float(), 0)              # [vn,tn]normal = normal.permute(1, 0, 2)                               # [vn,tn,2]normal = normal*torch.unsqueeze(all_inlier, 2)                 # [vn,tn,2] outlier is all zerob = torch.sum(normal*torch.unsqueeze(coords, 0), 2)             # [vn,tn]ATA = torch.matmul(normal.permute(0, 2, 1), normal)             # [vn,2,2]ATb = torch.sum(normal*torch.unsqueeze(b, 2), 1)                # [vn,2]# try:all_win_pts = torch.matmul(b_inv(ATA), torch.unsqueeze(ATb, 2)) # [vn,2,1]# except:#    __import__('ipdb').set_trace()batch_win_pts.append(all_win_pts[None,:,:, 0])batch_win_pts = torch.cat(batch_win_pts)return batch_win_pts

3.和论文中公式(3)和(4)一致的代码,生成均值特征点和方差

    前面部分和 ransac_voting_layer_v3 代码相同,后边部分代码也相对好理解,不做解释。


def estimate_voting_distribution_with_mean(mask, vertex, mean, round_hyp_num=256, min_hyp_num=4096, topk=128, inlier_thresh=0.99, min_num=5, max_num=30000, output_hyp=False):b, h, w, vn, _ = vertex.shapeall_hyp_pts, all_inlier_ratio = [], []for bi in range(b):k = 0cur_mask = mask[bi] == k + 1foreground = torch.sum(cur_mask)# if too few points, just skip itif foreground < min_num:cur_hyp_pts = torch.zeros([1, min_hyp_num, vn, 2], dtype=torch.float32, device=mask.device).float()all_hyp_pts.append(cur_hyp_pts)  # [1,vn,2]cur_inlier_ratio = torch.ones([1, min_hyp_num, vn], dtype=torch.int64, device=mask.device).float()all_inlier_ratio.append(cur_inlier_ratio)continue# if too many inliers, we randomly down sample itif foreground > max_num:selection = torch.zeros(cur_mask.shape, dtype=torch.float32, device=mask.device).uniform_(0, 1)selected_mask = (selection < (max_num / foreground.float()))cur_mask *= selected_maskforeground = torch.sum(cur_mask)coords = torch.nonzero(cur_mask).float()  # [tn,2]coords = coords[:, [1, 0]]direct = vertex[bi].masked_select(torch.unsqueeze(torch.unsqueeze(cur_mask, 2), 3))  # [tn,vn,2]direct = direct.view([coords.shape[0], vn, 2])tn = coords.shape[0]round_num = np.ceil(min_hyp_num/round_hyp_num)cur_hyp_pts = []cur_inlier_ratio = []for round_idx in range(int(round_num)):idxs = torch.zeros([round_hyp_num, vn, 2], dtype=torch.int32, device=mask.device).random_(0, direct.shape[0])# generate hypothesishyp_pts = ransac_voting.generate_hypothesis(direct, coords, idxs)  # [hn,vn,2]# voting for hypothesisinlier = torch.zeros([round_hyp_num, vn, tn], dtype=torch.uint8, device=mask.device)ransac_voting.voting_for_hypothesis(direct, coords, hyp_pts, inlier, inlier_thresh)  # [hn,vn,tn]inlier_ratio = torch.sum(inlier, 2)                     # [hn,vn]inlier_ratio = inlier_ratio.float()/foreground.float()    # ratiocur_hyp_pts.append(hyp_pts)cur_inlier_ratio.append(inlier_ratio)cur_hyp_pts = torch.cat(cur_hyp_pts, 0)cur_inlier_ratio = torch.cat(cur_inlier_ratio, 0)all_hyp_pts.append(torch.unsqueeze(cur_hyp_pts, 0))all_inlier_ratio.append(torch.unsqueeze(cur_inlier_ratio, 0))all_hyp_pts = torch.cat(all_hyp_pts, 0)               # b,hn,vn,2all_inlier_ratio = torch.cat(all_inlier_ratio, 0)     # b,hn,vn# raw_hyp_pts=all_hyp_pts.permute(0,2,1,3).clone()# raw_hyp_ratio=all_inlier_ratio.permute(0,2,1).clone()all_hyp_pts = all_hyp_pts.permute(0, 2, 1, 3)            # b,vn,hn,2all_inlier_ratio = all_inlier_ratio.permute(0, 2, 1)    # b,vn,hnthresh = torch.max(all_inlier_ratio, 2)[0]-0.1         # b,vnall_inlier_ratio[all_inlier_ratio < torch.unsqueeze(thresh, 2)] = 0.0diff_pts = all_hyp_pts-torch.unsqueeze(mean, 2)                  # b,vn,hn,2weighted_diff_pts = diff_pts * torch.unsqueeze(all_inlier_ratio, 3)cov = torch.matmul(diff_pts.transpose(2, 3), weighted_diff_pts)  # b,vn,2,2cov /= torch.unsqueeze(torch.unsqueeze(torch.sum(all_inlier_ratio, 2), 2), 3)+1e-3 # b,vn,2,2# if output_hyp:#     return mean,cov,all_hyp_pts,all_inlier_ratio,raw_hyp_pts,raw_hyp_ratioreturn mean, cov

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

花朵识别系统Python+卷积神经网络算法+人工智能+深度学习+计算机课设项目+TensorFlow+模型训练

一、介绍 花朵识别系统。本系统采用Python作为主要编程语言&#xff0c;基于TensorFlow搭建ResNet50卷积神经网络算法模型&#xff0c;并基于前期收集到的5种常见的花朵数据集&#xff08;向日葵、玫瑰、蒲公英、郁金香、菊花&#xff09;进行处理后进行模型训练&#xff0c;最…

解决DockerDesktop启动redis后采用PowerShell终端操作

如图&#xff1a; 在启动redis容器后&#xff0c;会计入以下界面 &#xff1a; 在进入执行界面后如图&#xff1a; 是否会觉得界面过于单调&#xff0c;于是想到使用PowerShell来操作。 步骤如下&#xff1a; 这样就能使用PowerShell愉快地敲命令了&#xff08;颜值是第一生…

【stm32笔记】使用rtt-studio与stm32CubeMx联合创建项目

使用rtt-studio与stm32CubeMx联合创建项目 创建rt-thread项目 设置项目信息 在项目资源管理器中“右击“&#xff0c;创建RRT studio 项目 双击“RT-Thread 项目“。 选择MCU&#xff0c;设置UART&#xff0c;以及调试方式。添加项目名称&#xff0c;点击“完成“按钮。 …

Redis的主从模式、哨兵模式、集群模式

最近学习了一下这三种架构模式&#xff0c;这里记录一下&#xff0c;仅供参考 目录 一、主从架构 1、搭建方式 2、同步原理 3、优化策略&#xff1a; 4、总结&#xff1a; 二、哨兵架构 1、搭建哨兵集群 2、RedisTemplate如何使用哨兵模式 三、分片集群架构 1&#…

集成学习详细介绍

以下内容整理于&#xff1a; 斯图尔特.罗素, 人工智能.现代方法 第四版(张博雅等译)机器学习_温州大学_中国大学MOOC(慕课)XGBoost原理介绍------个人理解版_xgboost原理介绍 个人理解-CSDN博客 集成学习(ensemble)&#xff1a;选择一个由一系列假设h1, h2, …, hn构成的集合…

AI运动小程序开发常见问题集锦一

截止到现在写博文时&#xff0c;我们的AI运动识别小程序插件已经迭代了23个版本&#xff0c;成功应用于健身、体育、体测、AR互动等场景&#xff1b;为了让正在集成或者计划进行功能扩展优化的用户&#xff0c;少走弯路、投入更少的开发资源&#xff0c;我们归集了一部分集中的…

Redis数据结构之set

一.set集合特性 集合类型也是保存多个字符串类型的元素的&#xff0c;但和list列表不一样&#xff0c;集合中的元素是无序的&#xff0c;而且元素不能够重复&#xff0c;不仅支持增删查改&#xff0c;还支持交集并集等操作 二.相关命令 1.sadd sadd key members…… 咱们把…

【机器学习】--- 决策树与随机森林

文章目录 决策树与随机森林的改进&#xff1a;全面解析与深度优化目录1. 决策树的基本原理2. 决策树的缺陷及改进方法2.1 剪枝技术2.2 树的深度控制2.3 特征选择的优化 3. 随机森林的基本原理4. 随机森林的缺陷及改进方法4.1 特征重要性改进4.2 树的集成方法优化4.3 随机森林的…

JavaScript ---案例(统计字符出现次数)

统计字符出现次数 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice-w…

深度学习之微积分预备知识点(2)

极限&#xff08;Limit&#xff09; 定义&#xff1a;表示某一点处函数趋近于某一特定值的过程&#xff0c;一般记为 极限是一种变化状态的描述&#xff0c;核心思想是无限靠近而永远不能到达 公式&#xff1a; 表示 x 趋向 a 时 f(x) 的极限。 知识点口诀解释极限的存在左…

LabVIEW软件维护的内容是什么呢?

LabVIEW软件维护涉及多个方面&#xff0c;确保程序的正常运行和长期稳定性。维护内容包括以下几个方面&#xff1a; 1. Bug修复 在开发和运行过程中&#xff0c;可能会出现各种软件问题或缺陷&#xff08;bugs&#xff09;。维护工作之一就是识别这些问题并通过修复程序中的代…

uniapp child.onFieldChange is not a function

uni-forms // 所有子组件参与校验,使用 for 可以使用 awiatfor (let i in childrens) {const child childrens[i];let name realName(child.name);if (typeof child.onFieldChange function) {const result await child.onFieldChange(tempFormData[name]);if (result) {…

【网络】TCP/IP 五层网络模型:网络层

最核心的就是 IP 协议&#xff0c;是一个相当复杂的协议 TCP 详细展开讲解&#xff0c;是因为 TCP 确实在开发中非常关键&#xff0c;经常用到&#xff0c;IP 则不同&#xff0c;和普通程序猿联系比较浅。和专门开发网络的程序猿联系比较紧密&#xff08;开发路由器&#xff0…

Qt5详细安装教程(包含导入pycharm)

1.自行下载Qt 2.双击进行安装 3.设置完成后勾选接受&#xff0c;跳转下一步 4.可选择安装位置&#xff0c;比较习惯安装在D盘 5.根据需求勾选对应组件安装 6.安装完成后&#xff0c;打开pycharm&#xff0c;进入settings—>选择ExternalTools&#xff0c;根据以下步骤进行配…

【WEB】EZ_Host

1、 2、解答 http://8762a9b0-5aa3-49f8-b8d2-54e4cb0746cc.www.polarctf.com:8090/?hostlocalhost;lshttp://8762a9b0-5aa3-49f8-b8d2-54e4cb0746cc.www.polarctf.com:8090/?hostlocalhost;cat flag即可看到答案

数据中台系统产品原型RP原型Axure高保真交互原型 源文件分享

在数字化时代&#xff0c;数据已经成为企业最宝贵的资产之一。为了更好地管理和利用这些数据&#xff0c;这边为大家整理了一套数据中台Axure高保真原型。这套原型致力于为企业提供全方位的数据服务&#xff0c;助力企业实现数据驱动的创新发展。 下载及预览地址&#xff1a;h…

828华为云征文|Flexus云服务器X实例部署宝塔运维面板

本次华为云Flexus云服务器X实例部署宝塔运维面板教学&#xff0c;这次是推陈出新啊 之前的云耀云服务器L实例已经很不错了&#xff0c;大力赞叹华为云的 同时感谢华为云提供优惠卷&#xff0c;只能说白嫖真是太棒了 华为云近期正在筹办华为云828企业节活动&#xff0c;90款免…

java重点学习-设计模式

十三 设计模式 工厂模式&#xff1a;spring中使用&#xff08;目的是&#xff1a;解耦&#xff09; 1.简单工厂 所有的产品都共有一个工厂&#xff0c;如果新增产品&#xff0c;则需要修改代码&#xff0c;违反开闭原则是一种编程习惯&#xff0c;可以借鉴这种编程思路 2.工厂方…

嵌入式入门小工程

此代码基于s3c2440 1.点灯 //led.c void init_led(void) {unsigned int t;t GPBCON;t & ~((3 << 10) | (3 << 12) | (3 << 14) | (3 << 16));t | (1 << 10) | (1 << 12) | (1 << 14) | (1 << 16);GPBCON t; }void le…

一个基于Gin + Vue 开发前后端分离的微型进存销系统,专为小微企业量身定制

前言 在这个信息化高速发展的时代&#xff0c;企业管理软件的需求日益增长&#xff0c;然而市面上许多现有的管理系统要么过于复杂&#xff0c;不适合小型企业的快速的需求&#xff1b;要么价格高昂&#xff0c;让许多初创企业望而却步。 针对这些痛点&#xff0c;我们迫切需…