目录
一、中值滤波
二、inpaint函数
一、中值滤波
中值滤波是一种非线性的信号处理方法,所以它是一种非线性滤波器,也是一种统计排序滤波器。它将每一像素点的灰度值设置为该点某邻域窗口内的所有像素点灰度值的中值。
目的:中值滤波对孤立的噪声像素即椒盐噪声、脉冲噪声具有良好的滤波效果,可以保持图像的边缘特性,不会使图像产生显著的模糊。
基本原理/思想:中值滤波是把数字图像或数字序列中一点的值用该点的一个邻域中各点值的中值代替,让周围的像素值接近真实值,从而消除孤立的噪声点。举个例子:
参考:https://blog.csdn.net/lixiao0314/article/details/120948652
?
?
二、inpaint函数
图像修复是图像恢复中的一个重要内容,其目的是利用图像现有的信息来恢复丢失的信 息。可用于旧照片中丢失信息的恢复,视频文字去除以及视频错误隐藏等。
简言之,图像修复就是对图像上信息缺损区域进行信息填充的过程,其目的就是为了对有信息缺损的图像进行恢复,并且使得观察者无法察觉到图像曾经缺损。图像恢复技术简单来说,就是利用那些被破坏区域的边缘,即是边缘的颜色和结构,繁殖和混合到损坏的图像中,来进行恢复图像。 ?
目前存在两大类图像修复技术:一类是用于修复小尺度缺损的数字图像修补(inpainting) 技术。即利用待修补区域的边缘信息,同时采用一种由粗到精的方法来估计等照度线的方向, 并采用传播机制将信息传播到待修补的区域内,以便达到较好的修补效果;另外一类是用于 填充图像大块丢失信息的图像补全技术。目前,这一技术分为以下两种方法:一种是基于图 像分解的修复方法,其主要思想是将图像分解为结构部分和纹理部分。其中,结构部分用 inpainting 的技术来修复,而纹理部分则采用纹理合成的方法来填充。另一种方法是用基于 块的纹理合成技术来填充丢失的信息,其主要思想是:首先从待修补区域的边界上选取一个 像素点,同时以该点为中心,根据图像的纹理特征,选择大小合适的纹理块,然后在待修补 区域的周围寻找与之最相近的纹理匹配块来替代该纹理块。近几年来,利用纹理合成来修复 大块丢失信息的图像合成技术取得了一定的研究成果。需要提醒的是,图像修复技术是一种 对视觉感知过程的学习和理解。它是一个不确定问题,没有唯一解的存在,解的合理性取决 于视觉系统的接受程度。换言之,为了达到较好的视觉效果,我们必须让修复效果更加符合 视觉感知的特性,使得图像看起来浑然一体,没有修改过的痕迹。
?
#include <iostream>
#include <opencv2/photo/photo.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace std;
using namespace cv;
#define WINDOW_NAME0 "【原始图】"
#define WINDOW_NAME1 "【中值滤波】"
#define WINDOW_NAME2 "【补修后的效果图】"
Mat srcImage, medianBlurImage, inpaintMask;
Point previousPoint(-1, -1);//原来的点坐标
static void On_Mouse(int event, int x, int y, int flages, void*);
int main(int argc, char** argv)
{
srcImage = imread("C:\\Users\\darren\\Desktop\\proj_test\\test\\test\\picture_test1\\2.jpg",-1);
if (!srcImage.data)
{
printf("读取错误!\n");
return false;
}
imshow(WINDOW_NAME0, srcImage);
//waitKey(0);
srcImage = srcImage.clone();
medianBlurImage = srcImage.clone();
inpaintMask = Mat::zeros(medianBlurImage.size(), CV_8U);
//中值滤波
medianBlur(srcImage, medianBlurImage, 7);
imshow(WINDOW_NAME1, medianBlurImage);//显示中值滤波图像
//waitKey(0);
setMouseCallback(WINDOW_NAME1, On_Mouse, 0); //设置鼠标回调消息
while (1)
{
char c = (char)waitKey();//获取键值
if (c == 27) break; //ESC,推出
if (c == '1') //键值为1,图像修补
{
Mat inpaintedImage;
inpaint(medianBlurImage, inpaintMask, inpaintedImage, 3, CV_INPAINT_TELEA);
imshow(WINDOW_NAME2, inpaintedImage);
}
}
return 0;
}
//鼠标回调函数
static void On_Mouse(int event, int x, int y, int flags, void*)
{
//左键弹起消息
if (event == EVENT_LBUTTONUP || !(flags & EVENT_FLAG_LBUTTON))
previousPoint = Point(-1, -1);
//左键按下消息
else if (event == EVENT_LBUTTONDOWN)
previousPoint = Point(x, y);
//按下并移动,绘制
else if (event == EVENT_MOUSEMOVE && (flags & EVENT_FLAG_LBUTTON))
{
Point pt(x, y);
if (previousPoint.x < 0)
previousPoint = pt;
//绘制白色线条
line(inpaintMask, previousPoint, pt, Scalar::all(255), 5, 8, 0);
line(medianBlurImage, previousPoint, pt, Scalar::all(255), 5, 8, 0);
previousPoint = pt;
imshow(WINDOW_NAME1, medianBlurImage);
}
}
|