【OpenCV】motion blur 的简单实现

先推荐界面比较丑,但是还不错的在线图片处理网站:

http://www168.lunapic.com/editor/

 

由于最近在做毕设了,结合前面关于图像处理和机器学习的操作,想做一些好玩的东西,其中有一部分需要构建一个模糊人脸库。一想到人脸照,大概都是超清晰的自拍(selfie)或者证件照,所以自然模糊的人脸好难找。。。

所以自己仿真。。做了一个小小的test set。。。

参杂了高斯模糊、失焦模糊、和运动模糊。。

opencv没有motion blur的filter

为了方便批量处理,写了一个小小小小的函数。。

 

 1 cv::Mat MotionBlur(cv::Mat srcImg, int filterSize) {
 2     int size = filterSize;
 3     cv::Mat filter = cv::Mat::zeros(size, size, CV_8UC1);
 4     cv::Mat result = cv::Mat(srcImg.size(), srcImg.type());
 5     for (int i = 0; i < size; i++)filter.at<uchar>(i, i) = (uchar)1;
 6     for (int i = 0; i < filter.rows; i++) {
 7         for (int j = 0; j < filter.cols; j++) {
 8             cout << (int)filter.at<uchar>(i, j) << " ";
 9         }
10         cout << endl;
11     }
12 
13     int len = size / 2;
14     
15     for (int r = 0; r < srcImg.rows; r++) {
16         for (int c = 0; c < srcImg.cols; c++) {
17             //mask
18             int red = 0, green = 0, blue = 0;
19             for (int i = r - len; i <= r + len; i++) {
20                 for (int j = c - len; j <= c + len; j++) {
21                     if (i < 0 || j < 0 || i >= srcImg.rows || j >= srcImg.cols) continue;
22                     blue += ((int)srcImg.at<cv::Vec3b>(i, j)[0]) * ((int)filter.at<uchar>(i - (r - len), j - (c - len)));
23                     green += ((int)srcImg.at<cv::Vec3b>(i, j)[1]) * ((int)filter.at<uchar>(i - (r - len), j - (c - len)));
24                     red += ((int)srcImg.at<cv::Vec3b>(i, j)[2]) * ((int)filter.at<uchar>(i - (r - len), j - (c - len)));
25                 }
26             }
27 
28             result.at<cv::Vec3b>(r, c)[0] = (uchar)(blue / size);
29             result.at<cv::Vec3b>(r, c)[1] = (uchar)(green / size);
30             result.at<cv::Vec3b>(r, c)[2] = (uchar)(red / size);
31         }
32     }
33 
34     cv::imshow("motion blur", result);
35     cv::waitKey(0);
36 
37     return result;
38 }

e.g.

filterSize = 9时, 角度45,矩阵如下

1 0 0 0 0 0 0 0 0

0 1 0 0 0 0 0 0 0

0 0 1 0 0 0 0 0 0

0 0 0 1 0 0 0 0 0

0 0 0 0 1 0 0 0 0

0 0 0 0 0 1 0 0 0

0 0 0 0 0 0 1 0 0

0 0 0 0 0 0 0 1 0

0 0 0 0 0 0 0 0 1 

 

卷积过后还要归一化, 即 * 1/9

 

转载于:https://www.cnblogs.com/cheermyang/p/6383266.html

运动跟踪是计算机视觉中的一个重要应用,OpenCV是一款常用的计算机视觉库,可以用Java语言进行开发。下面是Java OpenCV实现运动跟踪的基本步骤: 1. 导入OpenCV库和JavaCV库。 2. 读取视频或者摄像头捕获的实时图像。 3. 将连续的帧转换为灰度图像,并使用高斯滤波器进行模糊处理。 4. 计算当前帧和上一帧之间的差异图,并进行二值化处理。 5. 对二值化图像进行形态学操作,如腐蚀和膨胀,以去除噪声和填充空洞。 6. 使用轮廓检测算法找到二值图像中的轮廓,并筛选出符合条件的运动物体轮廓。 7. 绘制矩形框或者圆圈标记出运动物体的位置和大小。 下面是Java OpenCV实现运动跟踪的示例代码: ```java import org.bytedeco.javacpp.opencv_core.*; import org.bytedeco.javacpp.opencv_imgproc.*; import org.bytedeco.javacpp.opencv_videoio.*; import org.bytedeco.javacpp.opencv_highgui.*; public class MotionDetection { public static void main(String[] args) { String filename = "test.mp4"; VideoCapture capture = new VideoCapture(filename); Mat currentImage = new Mat(); Mat previousImage = new Mat(); Mat grayImage1 = new Mat(); Mat grayImage2 = new Mat(); Mat differenceImage = new Mat(); Mat thresholdImage = new Mat(); if (!capture.isOpened()) { System.out.println("Error loading video!"); return; } while (true) { capture.read(currentImage); if (currentImage.empty()) { System.out.println("End of video"); break; } cvtColor(currentImage, grayImage1, COLOR_BGR2GRAY); GaussianBlur(grayImage1, grayImage1, new Size(21, 21), 0); if (previousImage.empty()) { previousImage = grayImage1.clone(); continue; } absdiff(previousImage, grayImage1, differenceImage); threshold(differenceImage, thresholdImage, 25, 255, THRESH_BINARY); Mat kernel = getStructuringElement(MORPH_RECT, new Size(3, 3)); erode(thresholdImage, thresholdImage, kernel, new Point(-1, -1), 2); dilate(thresholdImage, thresholdImage, kernel, new Point(-1, -1), 2); MatVector contours = new MatVector(); findContours(thresholdImage, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE); for (int i = 0; i < contours.size(); i++) { double area = contourArea(contours.get(i)); if (area < 500) continue; Rect rect = boundingRect(contours.get(i)); rectangle(currentImage, rect, new Scalar(0, 0, 255), 2); } imshow("Motion Detection", currentImage); if (waitKey(25) == 27) break; previousImage = grayImage1.clone(); } } } ``` 在这个例子中,我们使用VideoCapture类读取视频文件,将连续的帧转换为灰度图像,并对相邻帧之间的差异图进行二值化处理和形态学操作,最后使用轮廓检测算法找到运动物体的轮廓并标记出来。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值