首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

OpenCV 矩陣卷積運算:從手動實作到 filter2D 優化

     編輯:關於C++

卷積核心原理

對每個像素,依其鄰域加權計算新值。以 3×3 銳化核為例:

公式:dst = 5*center - up - down - left - right,相當於 3×3 核與鄰域做內積。

手動實作銳化濾波器


void Sharpen(const Mat& src, Mat& dst) {
    CV_Assert(src.depth() == CV_8U);
    dst.create(src.size(), src.type());
    int nChannels = src.channels();

    for (int j = 1; j < src.rows - 1; ++j) {
        const uchar* prev = src.ptr<uchar>(j-1);
        const uchar* curr = src.ptr<uchar>(j);
        const uchar* next = src.ptr<uchar>(j+1);
        uchar* out = dst.ptr<uchar>(j);

        for (int i = nChannels; i < nChannels*(src.cols-1); ++i) {
            *out++ = saturate_cast<uchar>(
                5*curr[i] - curr[i-nChannels] - curr[i+nChannels] - prev[i] - next[i]
            );
        }
    }
    // 邊界設為 0
    dst.row(0).setTo(0); dst.row(dst.rows-1).setTo(0);
    dst.col(0).setTo(0); dst.col(dst.cols-1).setTo(0);
}

關鍵優化點:使用 ptr<uchar>(row) 取得行指標,單行連續掃描,避免 at() 重複計算地址。

結果比較

原圖:

銳化後:

OpenCV 內建 filter2D 一鍵替代


Mat kernel = (Mat_<char>(3,3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
filter2D(src, dst, src.depth(), kernel);
  • filter2D 內部針對 SSE/AVX、平行化深度優化。
  • 實測:手動迴圈 ~21 ms,filter2D ~7 ms(同環境)。
  • 邊界處理預設 BORDER_REFLECT_101,可自訂。

完整程式碼參考

OpenCV 官方範例:mat_mask_operations.cpp

最佳實務建議

  1. 生產程式碼優先使用 filter2D,除非需自訂極特殊邊界/權重邏輯。
  2. 手寫迴圈時:連續記憶體單行掃描 + 指標運算 + saturate_cast 是標準模板。
  3. 大核(> 5×5)考慮可分離濾波或 FFT 卷積進一步加速。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved