­

OpenCV3入門(十三)圖像運動模糊

  • 2020 年 3 月 14 日
  • 筆記

1、原理

運動模糊產生: 由於相機傳感器或物體相對運動, 按快門瞬間造成圖像產生運動模糊。

在用攝像機獲取景物圖像時,如果在相機曝光期間景物和攝像機之間存在相對運動,例如用照相機拍攝快速運動的物體,或者從行駛中的汽車上拍攝外面靜止不動的景物時,拍得的照片都可能存在模糊的現象,這種由於相對運動造成圖像模糊現象就是運動模糊。運動模糊是一種圖片“退化”現象,無法反應真實的場景。

假設圖像f(x,y)進行平面運動,x(t0)和y(t0)分別是在x和y方向上隨時間變化的量。那麼介質上(如膠片或數字存儲器)上任意點的曝光總數是通過對時間間隔內瞬間曝光量的積分得到的, 圖像系統的快門在該段時間是開着的。假設快門開關所用的時間很短,因此光學成像過程不會受到圖像運動干擾。運動模糊產生式:

 g(x,y): 代表運動模糊後在坐標(x,y)的結果

T:代表曝光時間

2、實現過程

1)對圖像方向分解為x和y方向;

2)因為圖像Mat坐標對應圖像的正下,所以翻轉Y軸;

3)分別計算圖像位移;

4)合併多個像素,防止溢出求平均值。

3、代碼實例

實驗代碼如下。只是簡單的實現了模糊原理,沒有考慮加性噪聲n(x)。

void MotionBlur(Mat& img, Mat& dst, int angle, int distance)  {      angle = -1*angle % 360;      double radian = ((double)angle + 180.0) / 180.0*3.1415926;      int dx = (int)((double)distance* cos(radian) + 0.5);      int dy = (int)((double)distance* sin(radian) + 0.5);        int sign = 0;      int height = img.rows;      int width = img.cols;      int chns = img.channels();        if (dst.empty())    dst.create(height, width, img.type());      int i, j, k;  int i0=0, j0=0, p, sum, count;      for (i = 0; i < height; i++)      {          unsigned char* dstData = (unsigned char*)dst.data + dst.step*i;          for (j = 0; j < width; j++)          {              for (k = 0; k < chns; k++)              {                  sum = 0, count = 0;                  sign = (dx > 0) ? 1 : -1;                  for (p = 0; p < abs(dx); p++)                  {                      i0 = i;                      j0 = j+p * sign;                      if (i0 >= 0 && i0 < height && j0 >= 0 && j0 < width)                      {                          count++;                          sum += img.at<Vec3b>(i0, j0)[k];                      }                  }                  sign = (dy > 0) ? 1 : -1;                  for (p = 0; p < abs(dy); p++)                  {                      i0 = i + p * sign;                      j0 = j;                      if (i0 >= 0 && i0 < height && j0 >= 0 && j0 < width)                      {                          count++;                          sum += img.at<Vec3b>(i0, j0)[k];                      }                  }                    if (count == 0)                  {                      dstData[j*chns + k] = img.at<Vec3b>(i0, j0)[k];                  }                  else                  {                      dstData[j*chns + k] = saturate_cast<uchar>(sum / (double)count + 0.5);                  }                }          }      }  }    void test_motion()  {      Mat src_img = imread("D:\WORK\5.OpenCV\LeanOpenCV\pic_src\pic14.bmp");      imshow("原圖", src_img);        Mat dst_img;      MotionBlur(src_img, dst_img, 180, 20);      imshow("motion", dst_img);  }

4、測試

測試1:驗證模糊的方向,輸入棋盤格圖,輸出為不同方向的模糊效果圖。

輸出效果圖如下。

測試2:模糊效果如下圖。

測試3:模糊效果如下圖。

5、參考文獻

Motion Deblur Filter

https://docs.opencv.org/3.4/d1/dfd/tutorial_motion_deblur_filter.html

圖像復原與重建篇——運動模糊

https://blog.csdn.net/jmu201521121021/article/details/80634361

PhotoShop算法實現進階-模糊濾鏡-運動模糊(二十四)

https://blog.csdn.net/kezunhai/article/details/41757681

 

技術博客,轉載請註明。

https://www.cnblogs.com/pingwen/p/12495168.html