影象復原與重建篇——運動模糊
阿新 • • 發佈:2018-11-29
運動模糊原理介紹
- 運動模糊產生: 由於相機感測器或物體相對運動, 按快門瞬間造成影象產生運動模糊。
- 假設影象
進行平面運動,
- : 代表運動模糊後在座標(x,y)的結果
- T:代表曝光時間
- 還有一個曝光係數s(0-1), 最終結果 = ,如果沒有曝光係數, 每個畫素灰度級都是0-255,積分後大部分個點都會超過255, 所以要曝光係數去微調,曝光係數值範圍(0,1)
運動模糊C++程式碼實現
/**
* @brief motionBlur 實現運動模糊
* @param srcImg 原圖
* @param destImg 模糊後圖片
* @param x 水平方向移動的距離
* @param y 垂直方向移動距離
* @param T 曝光時間
* param s 曝光係數
* @return null
* @note by jsc 0527
*
*/
void motionBlur(cv::Mat srcImg, cv::Mat &destImg, double x, double y, int T, double s){
int width;
int height;
width = srcImg.cols;
height = srcImg.rows;
if(srcImg.empty()){
std::cout<<"image is empty!!";
return;
}
double tempX;
double tempY;
int sumValue;
int tempValue;
destImg = cv::Mat::zeros(height,width, CV_64FC1);
srcImg.convertTo(srcImg, CV_64FC1);
for(int i = 0; i < height; i++){
for(int j = 0; j < width; j++){
tempX = 0;
tempY =0;
sumValue = 0;
tempValue= 0;
for(int t = 0; t < T; t++){
tempY = (double)i - (double)t / (double)T * x; // 水平
tempX = (double)j - (double)t / (double)T * y; // 垂直
tempX = (tempX - (int)tempX) >= 0.5 ? ceil(tempX) : floor(tempX);
tempY = (tempY - (int)tempY) >= 0.5 ? ceil(tempY) : floor(tempY);
tempX = tempX < 0 ? 0 : tempX;
tempY = tempY < 0 ? 0 : tempY;
tempX = tempX >= width ? width - 1 : tempX;
tempY = tempY >= height ? height - 1 : tempY;
tempValue =(int)( srcImg.at<double>((int)tempY, (int)tempX)*s); // 模糊後的畫素值
// std::cout << tempX <<" "<<tempY << " "<<tempValue<< std::endl;
sumValue += tempValue; // 積分累加
}
sumValue = sumValue > 255 ? 255 : sumValue;
// std::cout << sumValue << std::endl;
destImg.at<double>(i, j) = (double)sumValue;
}
}
destImg.convertTo(destImg, CV_8UC1);
}
- demo
main.cpp
#include <opencv2/opencv.hpp>
#include <string.h>
#include <iostream>
#include <math.h>
void main(){
cv::Mat img = cv::imread("../face.jpg");
cv::Mat result;
cv::Mat grayImage;
cv::cvtColor(img,grayImage, CV_BGR2GRAY);
motionBlur(grayImage, result, 10, 10, 10, 0.2);
cv::imshow("gray", grayImage);
cv::imshow("motionBlur Image", result);
cv::waitKey();
}