此代码用于实现模糊运动的添加与消除。

原理:在已知模糊运动核的前提下,可通过核线性卷积的形式对图像添加运动模糊,

反之也可利用该核精确的去除该运动模糊。

说明:本例代码是在梳理前人代码的基础上整理得到,仅使用了C++常用库与opencv2.4.5

AddMotionBlur的createLinearFilter函数在opencv3+版本中已经去除,故而建议只用opencv2+

ker 核的大小不能过大,例如,以lena图为例,ker的len为20时,会导致无法复原。

ker 核的生成可参考以下matlab的实现

此例对应的matlab代码实现:点击打开链接

OpenCV实现代码:Linux版本

/*--------------------------- motion blur and demotion blur --------------------------------*/
// 此代码用于实现模糊运动的添加与消除。
// 原理:在已知模糊运动核的前提下,可通过核线性卷积的形式对图像添加运动模糊,
//       反之也可利用该核精确的去除该运动模糊。
// 说明:本例代码是在梳理前人代码的基础上整理得到,仅使用了C++常用库与opencv2.4.5
//       AddMotionBlur的createLinearFilter函数在opencv3+版本中已经去除,故而建议只用opencv2+
//       ker 核的大小不能过大,例如,以lena图为例,ker的len为20时,会导致无法复原。
// Input:
//      彩色三通道图像,在读取时转化为灰度图
// output:
//      添加运动模糊的单通道灰度图,或去除运动模糊后的单通道灰度图
// version: 1.0
// date: 2018/6/6
// by xie qunyi
// 转载请注明:
/*------------------------------------------------------------------------------------------*/#include <iostream>
#include <opencv2/opencv.hpp>using namespace std;
using namespace cv;// Create an image of complex number type (2 channels to store
// real part and imaginary part) from an input grayscale image
// src : single channel grayscale image input
// dst : two channel complex image output
void i2z(cv::Mat src, cv::Mat& dst)
{//convert the image to float type, create another one filled with zeros, //and make an array of these 2 imagescv::Mat im_array[] = { cv::Mat_<float>(src), cv::Mat::zeros(src.size(), CV_32F) };//combine as a 2 channel image to represent a complex number type imagecv::Mat im_complex; cv::merge(im_array, 2, im_complex);//copy to destinationim_complex.copyTo(dst);
}// convert a 2 channel complex image to a single channel grayscale image
// by getting magnitude
// src : two channel complex image input
// dst : single channel grayscale image output
void z2i(cv::Mat src, cv::Mat& dst)
{//split the complex image to 2cv::Mat im_tmp[2]; cv::split(src, im_tmp);//get absolute valuecv::Mat im_f; cv::magnitude(im_tmp[0], im_tmp[1], im_f);//copy to destinationim_f.copyTo(dst);
}// return complex image C = A./B
// if A = a+b*i and B = c+d*i;
// then C = A./B = ((a*c+b*d)/(c^2+d^2))+((b*c-a*d)/(c^2+d^2))*i
cv::Mat complexDiv(const cv::Mat& A, const cv::Mat& B)
{cv::Mat A_tmp[2]; cv::split(A, A_tmp);cv::Mat a, b;A_tmp[0].copyTo(a);A_tmp[1].copyTo(b);cv::Mat B_tmp[2]; cv::split(B, B_tmp);cv::Mat c, d;B_tmp[0].copyTo(c);B_tmp[1].copyTo(d);cv::Mat C_tmp[2];cv::Mat g = (c.mul(c)+d.mul(d));C_tmp[0] = (a.mul(c)+b.mul(d))/g;C_tmp[1] = (b.mul(c)-a.mul(d))/g;cv::Mat C;cv::merge(C_tmp, 2, C);return C;
}// add motion blur to the src image
// motion degree is depended on the kernel ker
// ker can be product by matlab func : fspecial
// matlab code : {LEN = 3; THETA = 0; ker = fspecial('motion', LEN, THETA);}
cv::Mat AddMotionBlur(const cv::Mat& src, const cv::Mat& ker)
{   // convert to float datacv::Mat sample_float;src.convertTo(sample_float, CV_32FC1);// motion blurcv::Point anchor(0, 0);double delta = 0;cv::Mat dst = cv::Mat(sample_float.size(), sample_float.type());Ptr<cv::FilterEngine> fe = cv::createLinearFilter(sample_float.type(), ker.type(), ker, anchor,delta, BORDER_WRAP, BORDER_CONSTANT, cv::Scalar(0));fe->apply(sample_float, dst);return dst;
}// remove motion blur which is added by the special kernel ker
// the same function in matlab is:
// {[hei,wid,~] = size(blurredimage);If = fft2(blurredimage);
//  Pf = fft2(ker,hei,wid); deblurred = ifft2(If./Pf);}
cv::Mat DemotionBlur(const cv::Mat& src, const cv::Mat& ker)
{ // IfMat blurred_co; i2z(src, blurred_co);Mat If;dft(blurred_co, If);// PfMat im_complex_ker; cv::Mat tmp = cv::Mat::zeros(src.rows, src.cols, CV_32FC1);ker.copyTo(tmp(cv::Rect(0,0,ker.cols,ker.rows)));Mat tmp_co;i2z(tmp, tmp_co);Mat Pf;dft(tmp_co, Pf);// If./Pfcv::Mat im_co = complexDiv(If, Pf);//Convert the DFT result into grayscaleMat im_de;dft(im_co, im_de, DFT_INVERSE+DFT_SCALE); Mat im_deblur; z2i(im_de, im_deblur);return im_deblur;
}int main(int argc, char** argv){// 读取测试样例const std::string ImageName = "./lena.jpg";cv::Mat DemoImage = cv::imread(ImageName, CV_LOAD_IMAGE_GRAYSCALE);// 运动模糊核float kernel[1][3] = {{0.333333333,0.33333333,0.33333333}};cv::Mat ker = cv::Mat(1, 3, CV_32FC1, &kernel);// 添加运动模糊cv::Mat blur = AddMotionBlur(DemoImage, ker);cv::imwrite("./blur.jpg", blur);// 去除运动模糊cv::Mat deblur = DemotionBlur(blur, ker);cv::imwrite("./deblur.jpg", deblur);return 0;
}

Opencv 实现 运动模糊的添加(motion blur)与消除(demotion blur)相关推荐

  1. OpenCV图像运动模糊

    def motion_blur(img, degree=10, angle=20):image = img.copy()# 这里生成任意角度的运动模糊kernel的矩阵, degree越大,模糊程度越 ...

  2. 【youcans 的 OpenCV 例程 200 篇】104. 运动模糊退化模型

    欢迎关注 『youcans 的 OpenCV 例程 200 篇』 系列,持续更新中 欢迎关注 『youcans 的 OpenCV学习课』 系列,持续更新中 [youcans 的 OpenCV 例程 2 ...

  3. 《Adobe After Effects CC完全剖析》——精确的运动模糊

    本节书摘来自异步社区<Adobe After Effects CC完全剖析>一书中的第2章,精确的运动模糊,作者 [美]Mark Christiansen(马克·克里斯琴森),译者 姜岩, ...

  4. 图像运动模糊原理及python实现

    一. motion blur 运动模糊是我们在日常生活中很常见的一种模糊.当我们按下快门拍照时,如果照片里的事物(或者我们的相机)正在运动的话,我们拍出的照片就会产生运动模糊. 二. motion f ...

  5. URP——后期处理特效——运动模糊Motion Blur

    Motion Blur 运动模糊效果模拟了真实相机拍摄物体运动速度快于曝光时间时图像中出现的模糊.这通常是由于物体快速移动,或曝光时间过长所致. 通用渲染管道(URP)只模糊摄像机的运动. Using ...

  6. Motion Blur 运动模糊 后期处理系列6

    Motion Blur 运动模糊 本文档主要是对Unity官方手册的个人理解与总结(其实以翻译记录为主:>) 仅作为个人学习使用,不得作为商业用途,欢迎转载,并请注明出处. 文章中涉及到的操作都 ...

  7. 动态模糊或运动模糊(motion blur) 介绍

    // 动态模糊或运动模糊(motion blur)是静态场景或一系列的图片像电影或是动画中快速移动的物体造成明显的模糊拖动痕迹. 摄影技术 当相机拍出影像时,不单只表现出单一时间的即时影像.由于技术限 ...

  8. 什么是运动模糊(Motion Blur)

    运动模糊是景物图象中的移动效果.它比较明显地出现在长时间暴光或场景内的物体快速移动的情形里. 为什么会出现运动模糊 摄影机的工作原理是在很短的时间里把场景在胶片上暴光.场景中的光线投射在胶片上,引起化 ...

  9. 运动模糊 motion blur

    为什么每秒24帧的速度对于电影来说已经足以获得很流畅的视觉效果,而对于电脑游戏来说却会显得磕磕碰碰呢?原因很简单,摄像机在工作的时候并非一帧一帧静止的拍摄,它所摄下的每一帧已经包含了1/24秒以内的所 ...

最新文章

  1. KVM精简教程(一):安装KVM
  2. 基于SegNet和UNet的遥感图像分割代码解读
  3. 计算机视觉应用开发功能图,《计算机视觉算法:基于OpenCV的计算机应用开发》 —1.3 理解计算机图像...
  4. 斥候密报_斥候密报《最强王者》三国幕后巾帼之黄月英_吉吉建站手游网
  5. 关于QTP 9.2 .NET 插件破解的尝试
  6. 如何往一个指定的地址写入一个值呢
  7. 三级网络技术IP地址
  8. 各省简称 拼音 缩写_中国省市县地区首字母缩写
  9. 计算机的音频管理器在哪里打开,Realtek高清晰音频管理器怎么找不到打开教程...
  10. HTML网页设计制作大作业-制作漫画网页设计6个页面(HTML+CSS+JavaScript)
  11. Unity3d之AR小游戏
  12. python中转义字符与格式化字符的混合使用
  13. VM是什么,干什么的
  14. D5渲染器电脑硬件配置Vol.1——操作系统丨显卡
  15. Travis CI 简介
  16. 南京2级计算机成绩查询,南京审计大学教务管理系统登录入口、成绩查询网上选课查分...
  17. nginx公网IP无法访问浏览器
  18. 线结构光光条直线方程提取问题分析
  19. Lane Detection in Low-light Conditions Using an Efficient DataEnhancement : Light Conditions Style
  20. net.sf.jasperreports.engine.util.JRFontNotFoundException: Font 华文宋体 is not available to the JVM. S

热门文章

  1. 新春送祝福,直接发红包。现金红包等你来拿~
  2. 树莓派3b+和 intel movidius 神经元计算棒2代 跑yolo v3 tiny
  3. dell g16 xianka
  4. threejs粒子效果
  5. 在B站被催更的恰饭视频是什么样的?
  6. iphone横竖屏切换,旋转屏幕
  7. Keil中文显示设置
  8. EXCEL,筛选合并单元格后的全部内容
  9. 华为帐号登录游戏显示无法连接服务器,玩手机游戏提示无法连接服务器
  10. 计算机二级Ms-Office选择题汇总