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

一、原理

運動模糊產生: 因爲相機傳感器或物體相對運動, 按快門瞬間形成圖像產生運動模糊。html

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

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

 g(x,y): 表明運動模糊後在座標(x,y)的結果學習

T:表明曝光時間測試

二、實現過程

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

2)由於圖像Mat座標對應圖像的正下,因此翻轉Y軸;.net

3)分別計算圖像位移;3d

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

三、代碼實例

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

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);
}

四、測試

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

輸出效果圖以下。

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

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

五、參考文獻

一、Motion Deblur Filter

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

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

http://www.javashuo.com/article/p-cjbzxenq-ep.html

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

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

四、《OpenCV3 編程入門》,電子工業出版社,毛星雨著

五、《學習OpenCV》,清華大學出版社,Gary Bradski, Adrian kaehler著

技術博客,轉載請註明。

http://www.javashuo.com/article/p-dhemdmkh-kt.html

相關文章
相關標籤/搜索