對每個像素,依其鄰域加權計算新值。以 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() 重複計算地址。
原圖:
銳化後:
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、平行化深度優化。filter2D ~7 ms(同環境)。BORDER_REFLECT_101,可自訂。OpenCV 官方範例:mat_mask_operations.cpp
filter2D,除非需自訂極特殊邊界/權重邏輯。