- 操作系统:ubuntu22.04
- OpenCV版本:OpenCV4.9
- IDE:Visual Studio Code
- 编程语言:C++11
算法描述
OpenCV 的 CUDA 模块(cudev) 中的一个仿函数生成器,用于创建一个 “截断阈值” 图像处理函数对象。
这个函数返回一个 仿函数对象(functor),用于在 GPU 上执行如下操作:
如果像素值大于 thresh,则将其设为 thresh;否则保留原值不变。
函数原型
__host__ __device__ ThreshTruncFunc<T> cv::cudev::thresh_trunc_func ( T thresh )
参数
- T thresh 阈值,如果像素值大于该值,则设置为 thresh
代码
#include <opencv2/cudev.hpp>
#include <opencv2/cudaimgproc.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
// CUDA kernel 使用 functor 对图像进行 "截断阈值" 处理
template <typename T>
__global__ void truncKernel(const T* input, T* output, int numPixels,
cv::cudev::ThreshTruncFunc<T> func) {
int idx = blockIdx.x * blockDim.x + threadIdx.x;
if (idx < numPixels) {
output[idx] = func(input[idx]);
}
}
int main() {
// Step 1: 读取图像并转为灰度图
cv::Mat bgr = cv::imread("/media/dingxin/data/study/OpenCV/sources/images/Lenna.png", cv::IMREAD_COLOR);
if (bgr.empty()) {
std::cerr << "Failed to load image!" << std::endl;
return -1;
}
cv::Mat src;
cv::cvtColor(bgr, src, cv::COLOR_BGR2GRAY); // 灰度图
int width = src.cols;
int height = src.rows;
int numPixels = width * height;
// Step 2: 分配 GPU 内存
uchar* d_input, *d_output;
cudaMalloc(&d_input, numPixels * sizeof(uchar));
cudaMalloc(&d_output, numPixels * sizeof(uchar));
cudaMemcpy(d_input, src.data, numPixels * sizeof(uchar), cudaMemcpyHostToDevice);
// Step 3: 创建 "截断阈值" 函数对象
auto func = cv::cudev::thresh_trunc_func<uchar>(128);
// Step 4: 启动 kernel
int blockSize = 256;
int numBlocks = (numPixels + blockSize - 1) / blockSize;
truncKernel<<<numBlocks, blockSize>>>(d_input, d_output, numPixels, func);
// Step 5: 下载结果
cv::Mat result(height, width, CV_8U);
cudaMemcpy(result.data, d_output, numPixels * sizeof(uchar), cudaMemcpyDeviceToHost);
// Step 6: 显示和保存结果
cv::imshow("original image", bgr);
cv::imshow("Trunc Threshold Result", result);
cv::waitKey(0);
cv::imwrite("trunc_result.jpg", result);
// Step 7: 清理资源
cudaFree(d_input);
cudaFree(d_output);
return 0;
}