- 操作系統:ubuntu22.04
- OpenCV版本:OpenCV4.9
- IDE:Visual Studio Code
- 編程語言:C++11
算法描述
在同一個線程塊(thread block)內,將 [beg, end) 范圍內的數據并行地填充為指定值 value。
它使用了 CUDA 線程協作機制(warp-level 或 block-level) 來實現高效的塊級填充,通常比簡單的逐線程填充更快。
函數原型
__device__ static __forceinline__ void cv::cudev::blockFill
(It beg,It end,const T & value
)
參數
參數名 | 類型 | 含義 |
---|---|---|
beg | It | 要填充的起始迭代器(或指針) |
end | It | 填充范圍的結束位置(不包含該位置) |
value | const T& | 用來填充的值 |
使用場景
- 初始化圖像局部區域;
- 構建 GPU 并行算法前的數據預處理;
- 圖像掩碼(mask)、ROI 區域清零;
- 需要多個線程協同完成連續內存初始化的任務。
代碼示例
#include <opencv2/core.hpp>
#include <opencv2/core/cuda.hpp>
#include <opencv2/cudev/block/block.hpp>
#include <iostream>
using namespace cv::cudev;// 定義 tile 大小為 16x16
#define TILE_SIZE 16// CUDA 核函數:使用 blockFill 填充圖像局部區域為指定值
__global__ void fillTileKernel(uchar* data, size_t pitch, int width, int height, uchar value) {// 獲取當前線程塊負責的圖像區域起點int x = blockIdx.x * TILE_SIZE + threadIdx.x;int y = blockIdx.y * TILE_SIZE + threadIdx.y;// 檢查是否在圖像范圍內if (x >= width || y >= height)return;// 計算該線程對應的全局指針位置uchar* ptr = data + y * pitch + x;// 使用 blockFill 填充當前 tile 區域為指定值blockFill(ptr, ptr + TILE_SIZE * TILE_SIZE, value);
}int main() {// 創建一個測試圖像(8UC1)cv::Mat h_src = cv::Mat::zeros(128, 128, CV_8UC1); // 全黑圖像std::cout << "Original image sample:\n" << h_src(cv::Rect(0, 0, 5, 5)) << std::endl;// 上傳到 GPUcv::cuda::GpuMat d_src;d_src.upload(h_src);// 設置 kernel 參數dim3 threads(TILE_SIZE, TILE_SIZE);dim3 blocks((h_src.cols + TILE_SIZE - 1) / TILE_SIZE,(h_src.rows + TILE_SIZE - 1) / TILE_SIZE);// 調用核函數,將每個 tile 填充為 255(白色)fillTileKernel<<<blocks, threads>>>(d_src.ptr<uchar>(), d_src.step, d_src.cols, d_src.rows, 255);// 下載結果cv::Mat h_dst;d_src.download(h_dst);// 顯示部分結果std::cout << "Filled image sample:\n" << h_dst(cv::Rect(0, 0, 5, 5)) << std::endl;return 0;
}
運行結果
Original image sample:
[ 0, 0, 0, 0, 0;0, 0, 0, 0, 0;0, 0, 0, 0, 0;0, 0, 0, 0, 0;0, 0, 0, 0, 0]
Filled image sample:
[255, 0, 255, 0, 255;0, 0, 0, 0, 0;0, 0, 0, 0, 0;0, 0, 0, 0, 0;0, 0, 0, 0, 0]