图像修补:cv::inpaint()
cv::inpaint()
是OpenCV中的一个函数,用于图像修补(image inpainting)。图像修补是一种图像处理技术,用于去除图像中的损坏或不需要的区域,然后用周围的信息填充这些区域,使图像看起来完整。这在图像修复、对象删除、障碍物遮挡处理等领域非常有用。
函数签名如下:
cv::inpaint(src, inpaintMask, dst, inpaintRadius, flags);
src
: 输入图像,需要进行修补的图像。inpaintMask
: 用于指定需要修补的区域的掩码。这是一个与输入图像大小相同的图像,其中需要修补的区域用白色标记,其余区域用黑色标记。dst
: 输出图像,修补后的结果将保存在这里。inpaintRadius
: 修补半径,指定了在修补时使用多少邻域像素来估算被修补像素的值。flags
: 修补算法的标志,可以选择不同的修补算法,如cv::INPAINT_TELEA
或cv::INPAINT_NS
。
示例用法已在之前的回答中提供。
cv::inpaint()
函数的工作原理是通过利用周围的信息来估算需要修补区域的像素值,以便生成修补后的图像。这是一个有用的工具,可用于图像修复和对象删除等任务。
#include <opencv2/opencv.hpp>
#include <iostream>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace std;
using namespace cv;
#include <iostream>
#include <fstream>
using namespace cv; //包含cv命名空间
#include <opencv2/core/core.hpp>
#define WINDOW_NAME1 "【原始图】" //为窗口标题定义的宏
#define WINDOW_NAME2 "【修补后的效果图】" //为窗口标题定义的宏
// 描述: 全局变量声明
Mat srcImagel, inpaintMask;
Point previousPoint(-1, -1);//原来的点坐标
//- -【On_Mouse()函数】
// 描述: 响应鼠标消息的回调函数
//
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(srcImagel, previousPoint, pt, Scalar::all(255), 5, 8, 0); previousPoint = pt;
imshow(WINDOW_NAME1, srcImagel);
}
}
//---------------------------【main()函数】- -----------------
// 描述: 控制台应用程序的入口函数, 我们的程序从这里开始执行
int main(int argc, char** argv)
{
//载入原始图并进行掩膜的初始化
Mat srcImage = imread("1.jpg", -1);
if (!srcImage.data) { printf("读取图片错误, 请确定目录下是否有 imread 函数指定图片存在~! \n"); return false; }
srcImagel = srcImage.clone();
inpaintMask = Mat::zeros(srcImagel.size(), CV_8U);
//显示原始图
imshow(WINDOW_NAME1, srcImagel);
//设置鼠标回调消息
setMouseCallback(WINDOW_NAME1, On_Mouse, 0);
//轮询按键, 根据不同的按键进行处理
while (1)
{
//获取按键键值
char c = (char)waitKey();
//键值为 ESC, 程序退出
if (c == 27)
break;
//键值为2,恢复成原始图像
if (c == '2')
{
inpaintMask = Scalar::all(0);
srcImage.copyTo(srcImagel);
imshow(WINDOW_NAME1, srcImagel);
}
//键值为1或者空格, 进行图像修补操作
if (c == '1' || c == ' ')
{
Mat inpaintedImage;
inpaint(srcImagel, inpaintMask, inpaintedImage, 3, INPAINT_TELEA);
imshow(WINDOW_NAME2, inpaintedImage);
}
}
return 0;
}