假设有如下锐化公式:
sharpened_pixel = 5 * current - left - right - up - down
代码实现如下:
void Sharpen(const cv::Mat& image, cv::Mat& result)
{
#ifndef _USE_KERNEL
result.create(image.size(), image.type());
int nchannels = image.channels();
for (int i = 1; i < image.rows - 1; i++) {
const uchar* previous = image.ptr<const uchar>(i - 1); // 上一行
const uchar* current = image.ptr<const uchar>(i); // 当前行
const uchar* next = image.ptr<const uchar>(i + 1); // 下一行
uchar* output = result.ptr<uchar>(i);
for (int j = 0; j < (image.cols - 1) * nchannels; j++) {
// 应用锐化算子
*output++ = cv::saturate_cast<uchar>(
5 * current[j] - current[j - nchannels] - current[j + nchannels] - previous[j] - next[j]);
}
}
result.row(0).setTo(cv::Scalar(0));
result.row(result.rows - 1).setTo(cv::Scalar(0));
result.col(0).setTo(cv::Scalar(0));
result.col(result.cols - 1).setTo(cv::Scalar(0));
return;
#endif // !_USE_KERNEL
cv::Mat kernel(3,3,CV_32F, Scalar(0));
kernel.at<float>(1, 1) = 5.0;
kernel.at<float>(0, 1) = -1.0;
kernel.at<float>(2, 1) = -1.0;
kernel.at<float>(1, 0) = -1.0;
kernel.at<float>(1, 2) = -1.0;
cout << image.depth() << endl;
cv::filter2D(image, result, image.depth(), kernel);
}
其中卷积函数:
CV_EXPORTS_W void filter2D( InputArray src, OutputArray dst, int ddepth,
InputArray kernel, Point anchor = Point(-1,-1),
double delta = 0, int borderType = BORDER_DEFAULT );
src :输入图像
dst:输出图像
ddepth:目标图像的期望深度
kernel:卷积核
anchor:内核的锚点,表示内部经过过滤的点的相对位置内核;锚应该位于内核内;默认值(-1,-1)表示锚点在内核中心
delta:offset值,默认为0
borderType:边界填充的类型,在滤波的过程中,会根据滤波器的尺寸在图像的边界填充一定的数量的像素值,以保证输入与输出具有相同的尺寸,这个参数指定边界填充的规则;目前支持一下几种规则
enum BorderTypes {
BORDER_CONSTANT = 0, //!< `iiiiii|abcdefgh|iiiiiii` with some specified `i`
BORDER_REPLICATE = 1, //!< `aaaaaa|abcdefgh|hhhhhhh`
BORDER_REFLECT = 2, //!< `fedcba|abcdefgh|hgfedcb`
BORDER_WRAP = 3, //!< `cdefgh|abcdefgh|abcdefg`
BORDER_REFLECT_101 = 4, //!< `gfedcb|abcdefgh|gfedcba`
BORDER_TRANSPARENT = 5, //!< `uvwxyz|abcdefgh|ijklmno`
BORDER_REFLECT101 = BORDER_REFLECT_101, //!< same as BORDER_REFLECT_101
BORDER_DEFAULT = BORDER_REFLECT_101, //!< same as BORDER_REFLECT_101
BORDER_ISOLATED = 16 //!< do not look outside of ROI
};