[论文阅读&代码]DehazeNet: An End-to-End System for Single Image Haze Removal

这篇具有很好参考价值的文章主要介绍了[论文阅读&代码]DehazeNet: An End-to-End System for Single Image Haze Removal。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

dehazenet代码,计算机视觉,python,深度学习

 摘要

  • 现有的单图像去雾方法使用很多约束和先验来获得去雾结果,去雾的关键是根据输入的雾图获得得到介质传输图(medium transmission map)
  • 这篇文章提出了一种端到端的可训练的去雾系统—Dehaze Net,用于估计介质传输图
  • Dehaze Net中,输入为雾图,输出为介质传输图,随后通过大气散射模型恢复无雾图像。
  • Dehaze Net网络采用卷积神经网络深度架构,该网络的每层都经过特殊的设计以应用现有的假设和先验。
  • Maxout单元用于特征提取,几乎可以产生大多数雾相关的特征。
  • 提出了一种非线性激活函数BRelu,其能够提高图像去雾的质量

Introduction

  • 当前的去雾方法:直方图方法;对比度方法;饱和度方法
  • 无雾图像的局部对比度高于有雾图像(最大对比度)、暗通道
  • Dehaze Net的设计受到现有的图像去雾的假设及原理的启发,其每层的参数都能够自动学习训练的雾图的特征
  • 本文的主要工作:设计了端到端的DehazeNet网络,应用现有的图像去雾原理对深度网络进行设计,能够直接得到雾图与其介质透射图之间的映射。
  • 非线性激活函数BRelu,利用双边约束来减小搜索空间,提高收敛性。

相关工作

大气散射模型

大气散射模型描述了雾的形成,该模型可以写作:

dehazenet代码,计算机视觉,python,深度学习

上式中,I(x)为雾图,J(x)为需要恢复的无雾图像,t(x)为介质透射率,为全局大气光。 大气散射模型中有三个未知数J(x)、t(x)及,要想恢复J(x),需要估计出t(x)及。 

dehazenet代码,计算机视觉,python,深度学习

 上图是雾天的成像过程,在雾霾天气中成像的过程中,反射能量减少引起的透射衰减J (x) t (x),导致亮度强度降低。空气灯α(1−t (x))由环境照明的散射形成,提高亮度并降低饱和度。α(1 − t (x))大气光是由环境光照散射形成的,能够增加亮度降低饱和度。

dehazenet代码,计算机视觉,python,深度学习

 介质透射率表示并未散射并到达相机的光,d(x)表示场景与相机的距离,是大气散射系数,根据上面的式子,当距离d(x)无限大的时候,t(x)趋于0,那么相机拍摄的图像I(x)就是全局大气光。如下式子所示。

dehazenet代码,计算机视觉,python,深度学习

 在实际的远距离成像过程中,d(x)不会无限大,但是可能会是一个相当大的数值,因此全局大气光的估计可以根据下面的式子(全局大气光可能是图像中亮度最大的点):

dehazenet代码,计算机视觉,python,深度学习

 根据大气散射模型,得到雾图的介质透射率是图像去雾恢复的关键环节。

雾相关的特征 

  • 暗通道

暗通道先验是在对大量室外无雾图片的观察分析得到的,大部分无雾图像中,至少有一个通道的像素点的亮度会非常低,甚至接近于0,暗通道定义为局部所有通道像素颜色的最小值。

dehazenet代码,计算机视觉,python,深度学习

 公式5中,表示图像I的RGB三个颜色通道,y属于像素点x的局部邻域,暗通道特征与图片中雾的浓度密切相关,能够被用于直接计算介质透射率t(x)。

  • 最大对比度

根据大气散射,雾会造成图像对比度的下降,局部对比度是指邻域中像素强度的方差与中心像素有关,邻域内局部对比度的最大值定义如下:

dehazenet代码,计算机视觉,python,深度学习

 在该邻域内,对比度特征与介质透射率之间的关系非常明显,可以通过最大化局部对比度增强图像的可见性。

  • 颜色衰减先验(HSV)

受雾霾影响,场景颜色发生褪色,同时patch的饱和度也剧烈下降,亮度也同时增加,产生一个较大的差值(亮度与饱和度的差),根据颜色衰减先验,这个差值可用于估计雾的浓度。

dehazenet代码,计算机视觉,python,深度学习

  •  色差(HSV)

原图与半反转(半逆)图像之间的色差可用于检测雾,对于无雾图像,其半逆图像的三个通道中的像素值不会全部翻转,导致原图与其半逆图像之间的色调变化较大。

dehazenet代码,计算机视觉,python,深度学习

 上式中,上标h表示HSV颜色空间的色度通道,根据公式8,介质透射率是色度差的反向传播。

DehazeNet

DehazeNet是一种可训练的端到端系统,可以明确地学习原始模糊图像及其相关介质传输图之间的映射关系。本部分介绍DehazeNet的层设计,并讨论这些设计如何与现有图像去雾方法中的思想(暗通道、最大对比度、颜色衰减先验、色差)相关联。

dehazenet代码,计算机视觉,python,深度学习

  •  特征提取

密集地提取这些与雾霾相关的特征相当于用适当的滤波器对输入的雾霾图像进行卷积,然后进行非线性映射。

Maxout激活函数用于降维的非线性映射,Maxout是一种简单的前馈非线性激活函数,用于多层感知或卷积神经网络。在CNN中使用时,通过对k个仿射特征映射进行像素最大化操作来生成一个新的特征映射。根据Maxout,设计了DehazeNet的第一层:

dehazenet代码,计算机视觉,python,深度学习

 W代表滤波器,B代表权重,*表示卷积操作

  • 多尺度映射

多尺度特征是有效的去雾霾方法,它密集地计算输入图像在多个空间尺度上的特征。多尺度特征提取也能有效地实现尺度不变性。例如,GoogLeNet中的初始架构使用了具有不同过滤器大小的并行卷积,并更好地解决了在输入图像中对齐对象的问题。

在DehazeNet的第二层使用并行卷积运算,其中任何卷积滤波器的大小都在3 × 3、5 × 5和7× 7之间,并且我们对这三个尺度使用相同数量的滤波器。

dehazenet代码,计算机视觉,python,深度学习

  •  局部极值

dehazenet代码,计算机视觉,python,深度学习

 相对于cnn的max-pooling通常会降低特征图的分辨率,局部极值操作被密集地应用于每个特征图像素,并且能够保留分辨率用于图像恢复。

  • 非线性回归

深度网络中非线性激活函数的标准选择包括Sigmoid和整流线性单元(ReLU)。前者更容易出现梯度消失的问题,导致网络训练收敛速度慢或局部最优性差。

为了克服梯度消失的问题,提出了提供稀疏表示的ReLU。然而,ReLU是为分类问题而设计的,并不完全适合图像恢复等回归问题。特别是,ReLU仅在值小于零时才抑制值。

dehazenet代码,计算机视觉,python,深度学习

 以上四层级联(串联)在一起形成了一个基于CNN的可训练端到端系统,其中与卷积层相关的滤波器和偏差是要学习的网络参数。这些层的设计可以与现有图像去雾方法的专业知识相联系。

dehazenet代码,计算机视觉,python,深度学习

 

import os
# import random
import cv2
import numpy as np
import random


def create_dataset(img_dir, data_dir, num_t=10, patch_size=16):
	# img_dir: dir of haze-free images
	# num_t: number of t(x)
	# patch_size: size of image patch
	
	img_path = os.listdir(img_dir)
	# 读取img_dir文件夹下所有文件

	path_train = []
	label_train = []

    # 包含训练样本的文件路径
    # 对应每个训练样本的标签,用于指示该样本属于哪个类别或者是什么类型
    # 通常在训练机器学习模型的过程中,需要同时提供训练数据集的特征和标签,以便模型能够学习到输入特征和相应标签之间的关系,并进行泛化预测
    
	
	for image_name in img_path:
		fullname = os.path.join(img_dir, image_name)
		img = cv2.imread(fullname)
		
		w, h, _ = img.shape
		
		num_w = int(w / patch_size)
		num_h = int(h / patch_size)
    # 将图像按照指定的大小(patch_size)划分成若干个小块,并计算图像中可以划分出多少个这样的小块。具体来说,num_w和num_h分别表示图像宽度方向和高度方向上,能够划分出的小块的数量。w和h分别是图像的宽度和高度,除以patch_size后,用Python的int()函数向下取整,得到的结果就是能够划分的小块的数量。
		for i in range(1, num_w-1):
			for j in range(1, num_h-1):
    # 循环变量 i 和 j 分别从1开始,而不是从0开始,可能是因为要避免处理图像的边缘区域。在图像处理中,通常会将边缘部分的像素值进行特殊处理,因为边缘处的像素往往不完整,可能会导致处理结果出现异常。因此,为了避免处理边缘像素的情况,通常会在处理图像时忽略边缘部分。在这个例子中,使用 range(1, num_w-1) 和 range(1, num_h-1) 作为循环变量,是为了避免处理图像的左、右、上、下四个边缘像素				

				free_patch = img[0 + i * patch_size:patch_size + i * patch_size,
					0 + j * patch_size:patch_size + j * patch_size, :]
				
				for k in range(num_t):
					t = random.random()
					hazy_patch = free_patch * t + 255 * (1 - t)
					picname = '%s'%i+'%s'%j+'%s'%k+image_name
					x = random.random()
					if x > 0.5:
						cv2.imwrite(os.path.join(data_dir, picname), hazy_patch)
						path_train.append(os.path.join(data_dir, picname))
						label_train.append(t)
	
	file = open('path_train.txt', mode='a')
	for i in range(len(path_train)):
		file.write(str(path_train[i])+'\n')
	file.close()
	file = open('label_train.txt', mode='a')
	for i in range(len(label_train)):
		file.write(str(label_train[i])+'\n')
	file.close()


create_dataset("E:/image enhancement/Dense_Haze_NTIRE19/dehaze", "E:/image enhancement/Dense_Haze_NTIRE19/dataset", num_t=10, patch_size=16)

在这段代码中,变量i被使用了多次,但是它们所指代的是不同的东西:

  1. 第一个i的使用是在最外层的循环中,它用来迭代图像中行数的数量(不包括边界):for i in range(1, num_w-1)
  2. 第二个i的使用是在保存图像补丁的文件名中:picname = '%s'%i+'%s'%j+'%s'%k+image_name。在这里,i用来表示图像中补丁的行索引。
  3. 第三个i的使用是在将文件路径写入“path_train.txt”文件的循环中:for i in range(len(path_train))。在这里,i用作循环计数器,用来迭代文件路径列表。

同样,代码中也有多个变量jk的使用,它们也分别指代不同的东西。

在上述代码中,num_t 是指每个图像块(image patch)所生成的模糊图像数量,即每个图像块会通过不同的 t 值来生成多个模糊图像。

在这个函数中,对于每个输入的原始图像,将其分割成多个图像块,每个图像块的大小为 patch_size * patch_size。对于每个图像块,会根据 num_t 生成多个模糊图像。具体地,使用一个随机的 t 值,根据以下公式生成模糊图像:

hazy_patch = free_patch * t + 255 * (1 - t)

其中,free_patch 是原始图像的一个图像块,t 是一个随机值,表示透射率(transmission rate), hazy_patch 是生成的模糊图像。这个公式通过将原始图像的颜色值乘以一个透射率值 t,再加上一个常数来模拟图像受到大气光影响的模糊效果。

因此,num_t 的值越大,每个图像块生成的模糊图像数量就越多。这样可以增加训练数据集的多样性,提高模型的泛化能力。但同时也会增加数据集的大小和训练时间。文章来源地址https://www.toymoban.com/news/detail-714093.html

import torch
import torch.nn as nn
from torch.utils.data.dataset import Dataset
from PIL import Image
import torchvision
from torchvision import transforms
import torch.utils.data as data
#import torchsnooper
import cv2

BATCH_SIZE = 128
# 每批处理的数据量
EPOCH = 10
# 迭代次数

# BRelu used for GPU. Need to add that reference in pytorch source file.
class BRelu(nn.Hardtanh):
	def __init__(self, inplace=False):
		super(BRelu, self).__init__(0., 1., inplace)

# 调用 nn.Hardtanh 的构造函数,并传递参数 0. 和 1. 作为 min_val 和 max_val,以及参数 inplace 作为布尔值。这样就创建了一个新的 BRelu 类,它继承了 nn.Hardtanh 类,并将其 min_val 和 max_val 参数设置为 0 和 1,相当于将 nn.Hardtanh 类限制在了这个范围内。
		
	def extra_repr(self):
		inplace_str = 'inplace=True' if self.inplace else ''
		return inplace_str

# 这段代码实现了一个BRelu类,它是nn.Hardtanh类的子类。nn.Hardtanh类是一个激活函数,用于将输入张量的值截断在指定的最小值和最大值之间。在这个BRelu类中,最小值为0,最大值为1,即将输入张量的负值截断为0,将大于1的值截断为1,其余值保持不变。




class DehazeNet(nn.Module):
	def __init__(self, input=16, groups=4):
		super(DehazeNet, self).__init__()
		self.input = input
		self.groups = groups
		self.conv1 = nn.Conv2d(in_channels=3, out_channels=self.input, kernel_size=5)
		self.conv2 = nn.Conv2d(in_channels=4, out_channels=16, kernel_size=3, padding=1)
		self.conv3 = nn.Conv2d(in_channels=4, out_channels=16, kernel_size=5, padding=2)
		self.conv4 = nn.Conv2d(in_channels=4, out_channels=16, kernel_size=7, padding=3)
		self.maxpool = nn.MaxPool2d(kernel_size=7, stride=1)
		self.conv5 = nn.Conv2d(in_channels=48, out_channels=1, kernel_size=6)
		self.brelu = nn.ReLU6()
		for name, m in self.named_modules():
			# lambda : 定义简单的函数    lambda x: 表达式
			# map(func, iter)  iter 依次调用 func
			# any : 有一个是true就返回true
			if isinstance(m, nn.Conv2d):
				# 初始化 weight 和 bias
				nn.init.normal_(m.weight, mean=0,std=0.001)
				if m.bias is not None:
					nn.init.constant_(m.bias, 0)
	
	def Maxout(self, x, groups):
		x = x.reshape(x.shape[0], groups, x.shape[1]//groups, x.shape[2], x.shape[3])
		x, y = torch.max(x, dim=2, keepdim=True)
		out = x.reshape(x.shape[0],-1, x.shape[3], x.shape[4])
		return out
	#BRelu used to CPU. It can't work on GPU.
	def BRelu(self, x):
		x = torch.max(x, torch.zeros(x.shape[0],x.shape[1],x.shape[2],x.shape[3]))
		x = torch.min(x, torch.ones(x.shape[0],x.shape[1],x.shape[2],x.shape[3]))
		return x
	
	def forward(self, x):
		out = self.conv1(x)
		out = self.Maxout(out, self.groups)
		out1 = self.conv2(out)
		out2 = self.conv3(out)
		out3 = self.conv4(out)
		y = torch.cat((out1,out2,out3), dim=1)
		# print(y.shape[0],y.shape[1],y.shape[2],y.shape[3],)
		y = self.maxpool(y)
		# print(y.shape[0],y.shape[1],y.shape[2],y.shape[3],)
		y = self.conv5(y)
		# y = self.relu(y)
		# y = self.BRelu(y)
		# y = torch.min(y, torch.ones(y.shape[0],y.shape[1],y.shape[2],y.shape[3]))
		y = self.brelu(y)
		y = y.reshape(y.shape[0],-1)
		return y


loader = torchvision.transforms.Compose([
	transforms.ToTensor(),
	transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])
augmentation = torchvision.transforms.Compose([
	transforms.RandomHorizontalFlip(0.5),
	transforms.RandomVerticalFlip(0.5),
	transforms.RandomRotation(30),
	transforms.ToTensor(),
	transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])


class FogData(Dataset):
	# root:图像存放地址根路径
	# augment:是否需要图像增强
	def __init__(self, root, labels, augment=True):
		# 初始化 可以定义图片地址 标签 是否变换 变换函数
		self.image_files = root
		self.labels = torch.cuda.FloatTensor(labels)
		self.augment = augment   # 是否需要图像增强
		# self.transform = transform

	def __getitem__(self, index):
		# 读取图像数据并返回
		if self.augment:
			img = Image.open(self.image_files[index])
			img = augmentation(img)
			img = img.cuda()
			return img, self.labels[index]
		else:
			img = Image.open(self.image_files[index])
			img = loader(img)
			img = img.cuda()
			return img, self.labels[index]

	def __len__(self):
		# 返回图像的数量
		return len(self.image_files)


path_train = []
file = open('path_train.txt', mode='r')
content = file.readlines()
for i in range(len(content)):
	path_train.append(content[i][:-1])

label_train = []
file = open('label_train.txt', mode='r')
content = file.readlines()
for i in range(len(content)):
	label_train.append(float(content[i][:-1]))
	#print(float(content[i][:-1]))

train_data = FogData(path_train, label_train, False)
train_loader = data.DataLoader(dataset=train_data, batch_size=BATCH_SIZE, shuffle=True, )

net = DehazeNet()
net.load_state_dict(torch.load(r'defog4_noaug.pth', map_location='cpu'))

#@torchsnooper.snoop()
def train():
	lr = 0.00001
	optimizer = torch.optim.Adam(net.parameters(), lr=0.0000005)
	loss_func = nn.MSELoss().cuda()
	for epoch in range(EPOCH):
		total_loss = 0
		for i, (x, y) in enumerate(train_loader):
	# 输入训练数据
	# 清空上一次梯度
			optimizer.zero_grad()
			output = net(x)
	# 计算误差
			loss = loss_func(output, y)
			total_loss = total_loss+loss
	# 误差反向传递
			loss.backward()
	# 优化器参数更新
			optimizer.step()
			if i % 10 == 5:
				print('Epoch', epoch, '|step ', i, 'loss: %.4f' % loss.item(), )
		print('Epoch', epoch, 'total_loss', total_loss.item())
	torch.save(net.state_dict(), r'defog4_noaug.pth')


#train()


def defog(pic_dir):
	img = Image.open(pic_dir)
	img1 = loader(img)
	img2 = transforms.ToTensor()(img)
	c, h, w = img1.shape
	patch_size = 16
	num_w = int(w / patch_size)
	num_h = int(h / patch_size)
	t_list = []
	for i in range(0, num_w):
		for j in range(0, num_h):
			patch = img1[:, 0 + j * patch_size:patch_size + j * patch_size,
				0 + i * patch_size:patch_size + i * patch_size]
			patch = torch.unsqueeze(patch, dim=0)
			t = net(patch)
			t_list.append([i,j,t])
	
	t_list = sorted(t_list, key=lambda t_list:t_list[2])
	a_list = t_list[:len(t_list)//100]
	a0 = 0
	for k in range(0,len(a_list)):
		patch = img2[:, 0 + a_list[k][1] * patch_size:patch_size + a_list[k][1] * patch_size,
				0 + a_list[k][0] * patch_size:patch_size + a_list[k][0] * patch_size]
		a = torch.max(patch)
		if a0 < a.item():
			a0 = a.item()
	for k in range(0,len(t_list)):
		img2[:, 0 + t_list[k][1] * patch_size:patch_size + t_list[k][1] * patch_size,
			0 + t_list[k][0] * patch_size:patch_size + t_list[k][0] * patch_size] = (img2[:,
			0 + t_list[k][1] * patch_size:patch_size + t_list[k][1] * patch_size,
			0 + t_list[k][0] * patch_size:patch_size + t_list[k][0] * patch_size] - a0*(1-t_list[k][2]))/t_list[k][2]
	defog_img = transforms.ToPILImage()(img2)
	defog_img.save('E:/image enhancement/Dense_Haze_NTIRE19/result/test.jpg')


defog("E:/image enhancement/demoes/DehazeNet-master/DehazeNet-master/data/girls.jpg")

到了这里,关于[论文阅读&代码]DehazeNet: An End-to-End System for Single Image Haze Removal的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【论文阅读】DeepVO: Towards End-to-End Visual Odometry with Deep Recurrent Convolutional Neural Networks

    相较于传统的视觉里程计,端到端的方法可以认为是把特征提取、匹配、位姿估计等模块用深度学习模型进行了替代。不同于那种用深度学习模型取代里程计框架一部分的算法,端到端的视觉里程计是直接将整个任务替换为深度学习,输入依然是图像流,结果也依然是位姿,

    2024年03月18日
    浏览(54)
  • End-to-End Object Detection with Transformers(论文解析)

    我们提出了一种将目标检测视为直接集合预测问题的新方法。我们的方法简化了检测流程,有效地消除了许多手工设计的组件的需求,如显式编码我们关于任务的先验知识的非极大值抑制过程或锚点生成。新框架的主要要素,称为DEtection TRansformer或DETR,包括一个基于集合的全

    2024年02月09日
    浏览(44)
  • DETR-《End-to-End Object Detection with Transformers》论文精读笔记

    End-to-End Object Detection with Transformers 参考:跟着李沐学AI-DETR 论文精读【论文精读】 在摘要部分作者,主要说明了如下几点: DETR是一个端到端(end-to-end)框架,释放了传统基于CNN框架的一阶段(YOLO等)、二阶段(FasterRCNN等)目标检测器中需要大量的人工参与的步骤,例如:

    2024年02月11日
    浏览(52)
  • 【论文笔记】End-to-End Diffusion Latent Optimization Improves Classifier Guidance

    Classifier guidance为图像生成带来了控制,但是需要训练新的噪声感知模型(noise-aware models)来获得准确的梯度,或使用最终生成的一步去噪近似,这会导致梯度错位(misaligned gradients)和次优控制(sub-optimal control)。 梯度错位(misaligned gradients):通过噪声感知模型指导生成模型时,两个

    2024年02月02日
    浏览(52)
  • 《Dense Distinct Query for End-to-End Object Detection》论文笔记(ing)

    作者这里认为传统个目标检测的anchor/anchorpoint其实跟detr中的query作用一样,可以看作query (1)dense query:传统目标检测生成一堆密集anchor,但是one to many需要NMS去除重复框,无法end to end。 (2)spare query 在one2one:egDETR,100个qeury,数量太少造成稀疏监督,收敛慢召回率低。 (

    2024年01月25日
    浏览(46)
  • DEFORMABLE DETR: DEFORMABLE TRANSFORMERS FOR END-TO-END OBJECT DETECTION 论文精读笔记

    DEFORMABLE DETR: DEFORMABLE TRANSFORMERS FOR END-TO-END OBJECT DETECTION 参考:AI-杂货铺-Transformer跨界CV又一佳作!Deformable DETR:超强的小目标检测算法! 摘要 摘要部分,作者主要说明了如下几点: 为了解决DETR中使用Transformer架构在处理图像特征图时的局限性而导致的收敛速度慢,特征空间

    2024年02月10日
    浏览(39)
  • 【Deformable DETR 论文+源码解读】Deformable Transformers for End-to-End Object Detection

    上一篇讲完了DETR相关原理和源码,打算继续再学习DETR相关改进。这次要解读的是21年发表的一篇论文: ICLR 2021:Deformable DETR: Deformable Transformers for End-to-End Object Detection 。 先感谢这位知乎大佬,讲的太细了: Deformable DETR: 基于稀疏空间采样的注意力机制,让DCN与Transformer一起玩

    2023年04月16日
    浏览(49)
  • Trajectory-guided Control Prediction for End-to-end Autonomous Driving论文学习

    端到端自动驾驶方法直接将原始传感器数据映射为规划轨迹或控制信号,范式非常简洁,从理论上避免了多模块设计的错误叠加问题和繁琐的人为规则设计。当前的端到端自动驾驶方法主要有两条独立的研究路线,要么基于规划轨迹来运行控制器,要么直接预测控制信号。端

    2024年02月05日
    浏览(55)
  • [文章阅读] EPro-PnP: Generalized End-to-End Probabilistic Perspective-n-Points for Monocular Object ...

    CVPR 2022 论文链接 源代码:Github 1.1 论文试图解决什么问题?这是否是一个新的问题? 试图解决:基于PnPDE的单目物体位姿估计,需要获得图像中点的3D深度(通过深度网络之类的方法)以及2D-3D之间的关联,然后通过PnP求解得到物体位姿;而PnP本质上不可导,使得无法通过反

    2024年02月03日
    浏览(50)
  • 论文解读《EPro-PnP: Generalized End-to-End Probabilistic Perspective-n-Points for Monocular Object Pose 》

    论文:《EPro-PnP: Generalized End-to-End Probabilistic Perspective-n-Points for Monocular Object Pose Estimation》 Code:https://github.com/tjiiv-cprg/epro-pnp (909 star) 作者的视频简单介绍:https://www.bilibili.com/video/BV13T411E7kb 摘要: 解决问题: 对于6D位姿估计,基于几何(PnP)的方法性能要好一些,但以前

    2024年02月03日
    浏览(59)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包