图片清晰度增强(锐化)方法浅探 - 拉普拉斯算法和高斯算法(c++ opencv)
最近几天研究对图片进行清晰度增强的方法,有一些比较肤浅的结论,记录一下备忘。
首先是如果想自己写一个对清晰度进行增强的方法,其实不太容易,我尝试过,遇到各种问题,比如边缘的圆滑度会被破坏,像素值改变的扩散程度不好把控,又不能不处理,所以如果不想花太大的力气,还是找一个知名度较高的公用方法吧。
目前搜索到的用的比较多的方法有拉普拉斯和高斯两种锐化的算法,前者锐化结果比较清晰,但略感粗糙,后者相对有点模糊,但是质感比较细腻,也算各有千秋吧。
void sharpen_laplas4(double weight=1.0, bool show = true)
{
Mat& m = srcImg; m.copyTo(nowImg); int w1 = (m.cols - 1), h1 = (m.rows - 1);
int la;
int row_size = nowImg.step, pixel_size = nowImg.elemSize(); uint8_t* buf, * row;
row = (uint8_t*)nowImg.data + row_size; buf = row + pixel_size;
int row_size0 = m.step, pixel_size0 = m.elemSize(); uint8_t* buf0, * buf01, * buf02, * row0;
row0 = (uint8_t*)m.data + row_size0; buf0 = row0 + pixel_size0; buf01 = buf0 - row_size0; buf02 = buf0 + row_size0;
for (int i = 1; i < h1; i++)
{
for (int j = 1; j < w1; j++)
{
//la = 4 * m.at(i, j) - m.at(i + 1, j) - m.at(i - 1, j) - m.at(i, j + 1) - m.at(i, j - 1); nowImg.at(i, j) = saturate_cast(nowImg.at(i, j) + la);
la = 4 * (*buf0) - *buf02 - *buf01 - *(buf0 + pixel_size0) - *(buf0 - pixel_size0); *buf= saturate_cast(*buf0 + la*weight);
buf += pixel_size; buf0 += pixel_size0; buf01 += pixel_size0; buf02 += pixel_size0;
}
row += row_size; buf = row + pixel_size;
row0 += row_size0; buf0 = row0 + pixel_size0; buf01 = buf0 - row_size0; buf02 = buf0 + row_size0;
}
if (show) { stringstream ss; ss << "laplas w=" << weight; cv::imshow(ss.str().c_str(), nowImg); }
}
// 锐化的weight值一般取-0.5, -1.0
void sharpen_gaus(double weight, bool show = true)
{
Mat& m = srcImg; m.copyTo(nowImg); Mat blur_img;
GaussianBlur(m, blur_img, Size(5, 5), 0, 0); // 对灰度图效果较好
//GaussianBlur(m, blur_img, Size(0, 0), 25); // 对彩色图效果较好
addWeighted(m, 1-weight, blur_img, weight, 0, nowImg);
if (show) { stringstream ss; ss << "gaus w=" << weight; cv::imshow(ss.str().c_str(), nowImg); }
}