- 操作系統:ubuntu22.04
- OpenCV版本:OpenCV4.9
- IDE:Visual Studio Code
- 編程語言:C++11
算法描述
OpenCV 的 CUDA 模塊(cudev) 中的一個設備端內聯函數,用于高效地計算兩個 uint 類型值的帶權重平均值。
該函數返回兩個無符號整數 a 和 b 的加權平均值,權重為:
return (a * 3 + b) / 4;
函數原型
__device__ __forceinline__ uint cv::cudev::vavg4(uint a, uint b)
參數
- a uint 第一個無符號整數(權重為 3)
- b uint 第二個無符號整數(權重為 1)
代碼
#include <opencv2/cudev.hpp>
#include <opencv2/cudev/util/simd_functions.hpp>using namespace cv::cudev;// CUDA kernel
template <typename T>
__global__ void computeWeightedAvgKernel(const PtrStep<T> src1,const PtrStep<T> src2,PtrStep<T> dst,int width,int height)
{int x = blockIdx.x * blockDim.x + threadIdx.x;int y = blockIdx.y * blockDim.y + threadIdx.y;if (x < width && y < height) {uint a = static_cast<uint>(src1(y, x));uint b = static_cast<uint>(src2(y, x));dst(y, x) = static_cast<T>(vavg4(a, b)); // (a*3 + b)/4}
}int main() {// 讀取兩幅圖像cv::Mat h_src1 = cv::imread("/media/dingxin/data/study/OpenCV/sources/images/img0.jpg", cv::IMREAD_GRAYSCALE);cv::Mat h_src2 = cv::imread("/media/dingxin/data/study/OpenCV/sources/images/img1.jpg", cv::IMREAD_GRAYSCALE);if (h_src1.empty() || h_src2.empty()) {std::cerr << "Failed to load images!" << std::endl;return -1;}// 上傳到 GPUcv::cuda::GpuMat d_src1, d_src2, d_avg;d_src1.upload(h_src1);d_src2.upload(h_src2);d_avg.create(h_src1.size(), h_src1.type());// 設置 kernel 參數dim3 block(16, 16);dim3 grid((d_src1.cols + block.x - 1) / block.x,(d_src1.rows + block.y - 1) / block.y);// 啟動 kernel(顯式指定模板參數 uchar)computeWeightedAvgKernel<uchar><<<grid, block>>>(d_src1, d_src2, d_avg, d_src1.cols, d_src1.rows);// 下載結果并顯示cv::Mat h_avg;d_avg.download(h_avg);cv::imshow("Original Image 1", h_src1);cv::imshow("Original Image 2", h_src2);cv::imshow("Weighted Averaged Image", h_avg);cv::waitKey(0);return 0;
}