赞
踩
相机矫正我们经常会用到,如果没有gpu加速,实际上矫正会很吃力,我们先用普通的矫正
cv::Mat undistort(cv::Mat img, cv::Mat K, cv::Mat D, int w, int h, float scale = 0.6)
{
cv::Mat Knew = K.clone();
//Knew = K.copy()
if (scale != 0)
{
Knew.at<double>(0, 0) = Knew.at<double>(0, 0) * scale;
Knew.at<double>(1, 1) = Knew.at<double>(1, 1) * scale;
}
cv::Size size(w, h);
cv::Mat map1, map2, dst;
int alpha = 0;
//cv::Mat NewCameraMatrix = getOptimalNewCameraMatrix(K, D,
// size, alpha, size, 0);
cv::fisheye::initUndistortRectifyMap(K, D, cv::Mat(), Knew, size, CV_16SC2, map1, map2);
cv::remap(img, dst, map1, map2, cv::INTER_LINEAR);
return dst;
}
问题就是cpu吃紧,下面我们还是使用带有cuda的gpu进行加速
#include <opencv2/opencv.hpp>
#include <opencv2/core/cuda.hpp>
#include <opencv2/cudaarithm.hpp>
#include <opencv2/cudawarping.hpp>
#include <opencv2/cudafilters.hpp>
// CUDA 核函数:实现畸变校正
__global__ void distortCorrectionKernel(cv::cuda::PtrStep<float> src, cv::cuda::PtrStep<float> dst, float* mapX, float* mapY, int width, int height) {
int x = threadIdx.x + blockIdx.x * blockDim.x;
int y = threadIdx.y + blockIdx.y * blockDim.y;
if (x < width && y < height) {
float newX = mapX[y * width + x];
float newY = mapY[y * width + x];
dst(y, x) = src(newY, newX);
}
}
int calc()
int main() {
// 读取相机的畸变参数
cv::Mat cameraMatrix, distCoeffs;
// 假设已经将相机的畸变参数填充到 cameraMatrix 和 distCoeffs 中
// 图像大小
cv::Size imageSize(640, 480);
// 计算畸变校正映射
cv::Mat mapX, mapY;
cv::initUndistortRectifyMap(cameraMatrix, distCoeffs, cv::Mat(), cv::getOptimalNewCameraMatrix(cameraMatrix, distCoeffs, imageSize, 1, imageSize, 0),
imageSize, CV_32FC1, mapX, mapY);
// 将映射表上传到 GPU
cv::cuda::GpuMat mapX_GPU, mapY_GPU;
mapX_GPU.upload(mapX);
mapY_GPU.upload(mapY);
// 加载输入图像到 GPU
cv::cuda::GpuMat srcImage_GPU;
// 假设您已经将输入图像加载到 srcImage_GPU 中
// 创建输出图像的 GPU 矩阵
cv::cuda::GpuMat dstImage_GPU(srcImage_GPU.size(), srcImage_GPU.type());
// 在 GPU 上执行畸变校正
dim3 block(32, 32);
dim3 grid((srcImage_GPU.cols + block.x - 1) / block.x, (srcImage_GPU.rows + block.y - 1) / block.y);
distortCorrectionKernel<<<grid, block>>>(srcImage_GPU, dstImage_GPU, mapX_GPU.ptr<float>(), mapY_GPU.ptr<float>(), srcImage_GPU.cols, srcImage_GPU.rows);
cudaDeviceSynchronize();
// 下载结果到 CPU
cv::Mat dstImage;
dstImage_GPU.download(dstImage);
// 现在您可以在 CPU 上使用校正后的图像了
return 0;
}
对于有cuda来说,这样做非常好,因为我们并不是只有一个算法放到cuda上做,而是具有很多算法需要经过cuda,对于这样的程序来说,我们直接使用,速度是最快的
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。