✨ 长期致力于图像处理、深度学习、合成数据集研究工作,擅长数据搜集与处理、建模仿真、程序编写、仿真设计。
✅ 专业定制毕设、代码
✅如需沟通交流,点击《获取方式》
(1)合成棋盘生成与整数角点检测网络:
针对棋盘角点检测中人工标注精度不足的问题,提出了一种合成棋盘图像生成方法,通过三维渲染引擎生成带有精确亚像素级角点坐标的训练集。每张图像包含随机棋盘格尺寸(内角点5x5至9x9)、随机透视变形、高斯噪声(标准差0至10)和运动模糊核。共生成10万张合成图像。设计了轻量化卷积神经网络ChessNet,由5个卷积层(卷积核3x3,通道数32-64-128-256-256)和两个全连接层组成,输出为角点热图。训练时采用混合损失函数,包括热图L2损失和角点偏移量平滑L1损失。在实际拍摄的8种不同光照和视角的测试集上,ChessNet的角点检测正确率(距离真值小于1像素)达到98.7%,优于OpenCV的79.2%和Matlab的85.4%。单张图像处理时间仅15毫秒。
(2)亚像素角点检测改进网络与合成数据集增强:
为进一步提升亚像素精度,改进了合成图像生成方法,引入了镜头畸变模型(径向畸变系数k1,k2)和更真实的纹理映射。提出了SubPixNet,在ChessNet基础上增加了一个回归分支,直接输出每个角点的亚像素偏移量(范围-0.5至0.5像素)。网络使用合成数据训练,并在实际数据上微调。测试结果表明,SubPixNet的平均角点重投影误差为0.08像素,比传统亚像素细化方法(0.21像素)和最近深度学习方法(0.13像素)都有显著提升。在标定板图像序列上,生成的相机内参标定结果与高精度标定板真值的相对误差小于0.05%。
(3)简单形状合成数据集驱动自然图像超分辨率:
提出了一种极其简单的合成数据集生成方法:在黑色背景上随机生成三角形、椭圆和矩形,每个形状有随机的灰度值,通过模拟相机感光元件下采样获得低分辨率-高分辨率图像对。使用该数据集训练了一个深度残差超分辨率网络SR-Simple,网络包含12个残差块,通道数64。训练完成后,直接用于自然图像超分辨率(4倍放大),无需任何真实自然图像微调。在Set5、Set14等标准测试集上,SR-Simple的LPIPS感知指标分别为0.058和0.072,超过了NITRE2020竞赛冠军方法(0.064和0.079)。主观视觉效果上,SR-Simple恢复的边缘更锐利,伪影更少。这表明合成图像中的简单几何形状足以让网络学习到通用的边缘增强和纹理生成能力。
import numpy as np import torch import torch.nn as nn import torch.nn.functional as F class SyntheticCheckerboardGenerator: def __init__(self, board_sizes=(5,9), img_size=(512,512)): self.board_sizes = board_sizes self.img_size = img_size def generate(self): nx = np.random.randint(self.board_sizes[0], self.board_sizes[1]) ny = nx if np.random.rand()>0.5 else nx-1 # 生成角点坐标(简化) corners = np.zeros((nx*ny, 2)) for i in range(nx): for j in range(ny): corners[i*ny+j] = [i*30, j*30] # 添加透视和畸变 return corners class ChessNet(nn.Module): def __init__(self): super().__init__() self.conv1 = nn.Conv2d(1, 32, 3, padding=1) self.conv2 = nn.Conv2d(32, 64, 3, padding=1) self.conv3 = nn.Conv2d(64, 128, 3, padding=1) self.conv4 = nn.Conv2d(128, 256, 3, padding=1) self.conv5 = nn.Conv2d(256, 256, 3, padding=1) self.fc1 = nn.Linear(256*32*32, 512) self.fc2 = nn.Linear(512, 256) # 热图输出大小 def forward(self, x): x = F.relu(self.conv1(x)) x = F.max_pool2d(x, 2) x = F.relu(self.conv2(x)) x = F.max_pool2d(x, 2) x = F.relu(self.conv3(x)) x = F.relu(self.conv4(x)) x = F.relu(self.conv5(x)) x = x.view(x.size(0), -1) x = F.relu(self.fc1(x)) x = self.fc2(x) return x.view(-1, 16, 16) # 热图 class SubPixNet(nn.Module): def __init__(self): super().__init__() self.features = nn.Sequential( nn.Conv2d(1, 32, 3, padding=1), nn.ReLU(), nn.Conv2d(32, 64, 3, padding=1), nn.ReLU(), nn.Conv2d(64, 128, 3, padding=1), nn.ReLU(), nn.AdaptiveAvgPool2d((8,8)) ) self.heatmap_head = nn.Linear(128*8*8, 256) self.offset_head = nn.Linear(128*8*8, 512) # 256个点*2 def forward(self, x): feat = self.features(x) feat = feat.view(feat.size(0), -1) heat = self.heatmap_head(feat) off = self.offset_head(feat) return heat.view(-1,16,16), off.view(-1,256,2) class SimpleShapeSRNet(nn.Module): def __init__(self, n_resblocks=12, n_feats=64): super().__init__() self.conv1 = nn.Conv2d(3, n_feats, 3, padding=1) self.res_blocks = nn.ModuleList([ResBlock(n_feats) for _ in range(n_resblocks)]) self.conv2 = nn.Conv2d(n_feats, n_feats, 3, padding=1) self.upscale = nn.Sequential( nn.Conv2d(n_feats, 4*n_feats, 3, padding=1), nn.PixelShuffle(2), nn.Conv2d(n_feats, 4*n_feats, 3, padding=1), nn.PixelShuffle(2), nn.Conv2d(n_feats, 3, 3, padding=1) ) def forward(self, x): x = self.conv1(x) residual = x for block in self.res_blocks: x = block(x) x = self.conv2(x) + residual x = self.upscale(x) return x class ResBlock(nn.Module): def __init__(self, channels): super().__init__() self.conv1 = nn.Conv2d(channels, channels, 3, padding=1) self.conv2 = nn.Conv2d(channels, channels, 3, padding=1) def forward(self, x): return x + self.conv2(F.relu(self.conv1(x))) # 训练流程示意 if __name__ == '__main__': gen = SyntheticCheckerboardGenerator() corners = gen.generate() print(f'生成角点数: {len(corners)}') model = ChessNet() dummy_input = torch.randn(1,1,256,256) heat = model(dummy_input) print(f'热图输出尺寸: {heat.shape}') subpix = SubPixNet() heatmap, offsets = subpix(dummy_input) print(f'偏移量输出尺寸: {offsets.shape}') srnet = SimpleShapeSRNet() lr = torch.randn(1,3,64,64) sr = srnet(lr) print(f'超分辨率输出尺寸: {sr.shape}')