圖像或者說圖片經常被噪聲腐蝕,或者說是舊照片的劃痕。
圖像修復技術簡單來說,就是利用那些被破壞區域的邊緣,即是邊緣的顏色和結構,繁殖和混合到損壞的圖像中,來進行修復圖像。下面的OpenCV代碼主要做的是將圖像中的字跡進行消除的效果。
如果圖像損壞的區域不是太大,修復效果可以達到很好的效果。畢竟修復的能力是有限的。
inpaint函數
在OpenCV中,圖像修補技術由inpaint函數實現,用來從掃描圖像中清除灰塵和劃痕,或者從靜態圖像或視頻中去除不需要的物體。
函數聲明如下:
void inpaint(InputArray src, InputArray inpaintMask, OutputArray dst, double inpaintRadius, int flags)
第一個參數,InputArray類型的src,也就是輸入圖像,用Mat類對象就可以了。並且要是8位單通道或者三通道圖像。
第二個參數,InputArray類型的inpaintMask,修復掩膜,爲8位單通道圖像。其中非0像素表示要修復的區域。
第三個參數,OutputArray類型的dst,函數調用後的運算結果保存在這裏,和輸入圖像有着一樣的大小和類型。
第四個參數,double類型的inpaintRadius,需要修補的每個點的圓形鄰域,爲修復算法參考的半徑。
第五個參數,int類型的flags,修補方法的標識符。如下
**INPAINT_NS 基於Navier-Stokes方程的方法
INPAINT_TELEA Alexandru Telea方法**
代碼如下:
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/photo/photo.hpp"
#include <iostream>
using namespace cv;
using namespace std;
#define WINDOW_NAME1 "【原始圖】"
#define WINDOW_NAME2 "【修補後】"
Mat srcImage1, inpaintMask;
// 原來的點座標
Point previousPoint(-1, -1);
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(srcImage1, previousPoint, pt, Scalar::all(255), 5, 8, 0);
previousPoint = pt;
imshow(WINDOW_NAME1, srcImage1);
}
}
int main(int argc, char ** argv)
{
Mat srcImage = imread("1.jpg", -1);
if(!srcImage.data)
{
printf("讀取照片錯誤,請確定目錄下是否有imread函數指定的圖片存在!\n");
return false;
}
srcImage1 = srcImage.clone();
inpaintMask = Mat::zeros(srcImage1.size(), CV_8U);
// 顯示原圖
imshow(WINDOW_NAME1, srcImage1);
// 設置消息回調消息
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(srcImage1);
imshow(WINDOW_NAME1, srcImage1);
}
// 按鍵爲1或者空格,則進行修補操作
if(c == '1' || c == ' ')
{
Mat inpaintedImage;
inpaint(srcImage1, inpaintMask, inpaintedImage, 3, INPAINT_TELEA);
imshow(WINDOW_NAME2, inpaintedImage);
}
}
return 0;
}
程序運行如下:
關於OpenCV和圖像處理以及模式識別更多的學習資料將繼續更新,敬請關注本博客。