<图像处理> 可分离滤波器核

可分离滤波器核

空间滤波器核是一个二维矩阵,若它能够表示为两个一维矩阵的乘积时,则表示该滤波器核是可分离的。
例如,一个3x3的核,
w = [ 1 1 1 1 1 1 1 1 1 ] w=\begin{bmatrix} 1 & 1 & 1\\ 1 & 1& 1\\ 1 & 1& 1\\ \end{bmatrix} w= 111111111
它可以表示为两个一维矩阵的乘积
c = [ 1 1 1 ] c=\begin{bmatrix} 1 & 1 & 1\\ \end{bmatrix} c=[111]
r = [ 1 1 1 ] r=\begin{bmatrix} 1 & 1 & 1\\ \end{bmatrix} r=[111]

w = c r T w=cr^T w=crT

性质

可分离核的重要性是卷积结合律性质导致的计算优势,如果有一个核 w w w,它可以分为两个简单的核并满足 w = w 1 ∗ w 2 w=w_1*w_2 w=w1w2,则其满足
w ∗ f = ( w 1 ∗ w 2 ) ∗ f = ( w 2 ∗ w 1 ) ∗ f = w 2 ∗ ( w 1 ∗ f ) = ( w 1 ∗ f ) ∗ w 2 w*f=(w_1*w_2)*f=(w_2*w_1)*f=w_2*(w_1*f)=(w_1*f)*w_2 wf=(w1w2)f=(w2w1)f=w2(w1f)=(w1f)w2
对于一个大小为 M ∗ N M*N MN的图像与大小为 m ∗ n m*n mn的核实现卷积,需要 M N m n MNmn MNmn次加法和乘法,如果核是可分离的,则需要 M N ( m + n ) MN(m+n) MN(m+n)次,可加速计算。

必要条件

要确定一个核是否可分离,只需要确定其秩是否为1。 因此确定某个矩阵的秩为1后,能够计算其两个分离的一维核,步骤如下

  1. 在核中找到任意一个非零元素,并将其表示为E;
  2. 找他该元素所在的行和列,表示为 c , r c,r c,r
  3. 可以得出两个一维核为 c c c r / E r/E r/E

示例

以x方向上的Sobel滤波核进行性能测试,比较 M N m n MNmn MNmn以及 M N ( m + n ) MN(m+n) MN(m+n)的处理时间,并与自带opencv 的cv::filter2D与cv::Sobel算子进行比较滤波效果。

int main()
{//x方向的Sobel核Mat kernel = (Mat_<char>(3, 3) <<-1, 0, 1,-2, 0, 2,-1, 0, 1);const char* imageName = ".....";Mat src = imread(imageName, IMREAD_GRAYSCALE);Mat srcBorder;copyMakeBorder(src, srcBorder, kernel.cols / 2, kernel.cols / 2, kernel.rows / 2, kernel.rows / 2, cv::BORDER_CONSTANT);//填充边缘clock_t start, end;//1.MNmnMat dst(src.rows, src.cols, CV_8UC1);start = clock();int sum = 0;for (int i = 1;i <= dst.rows;i++){for (int j = 1;j <= dst.cols;j++){sum = 0;for (int m = 0;m < kernel.rows;m++){for (int n = 0;n < kernel.cols;n++){sum += (int)(srcBorder.ptr<uchar>(i + m - 1)[j + n - 1] * kernel.ptr<char>(m)[n]);}}dst.ptr<uchar>(i - 1)[j - 1] = (uchar)(sum < 0 ? 0 : (sum > 255 ? 255 : sum));}}end = clock();std::cout << "1.常规计算(MNmn):" << end - start << std::endl;//2.可分离滤波计算Mat _src2(src.rows + kernel.rows / 2 + 1, src.cols + kernel.cols / 2 + 1, CV_32SC1);_src2 = Scalar::all(0);Mat dst2(src.rows, src.cols, CV_8UC1);start = clock();//分离卷积核char kernelRow[3] = { 1,0,-1 };char kernelCol[3] = { -1,-2,-1 };for (int i = 1;i <= dst2.rows;i++){for (int j = 1;j <= dst2.cols;j++){sum = 0;for (int m = 0;m < 3;m++){sum += (int)(srcBorder.ptr<uchar>(i)[j + m - 1] * kernelRow[m]);}_src2.ptr<short>(i)[j] = sum;}}for (int i = 1;i <= dst2.rows;i++){for (int j = 1;j <= dst2.cols;j++){sum = 0;for (int n = 0;n < 3;n++){sum += (int)(_src2.ptr<short>(i + n - 1)[j] * kernelCol[n]);}dst2.ptr<uchar>(i - 1)[j - 1] = (uchar)(sum < 0 ? 0 : (sum > 255 ? 255 : sum)); //防止溢出。opencv中使用内联函数saturate_cast<T>()}}end = clock();std::cout << "2.可分离核计算MN(m+n):" << end - start << std::endl;//3.opencv-filter2D计算Mat dst3;start = clock();cv::filter2D(src, dst3, -1, kernel, Point(-1, -1), 0.0, BORDER_CONSTANT);end = clock();std::cout << "3.opencv-filter2D计算:" << end - start << std::endl;//4.opencv-sobel计算Mat dst4;start = clock();cv::Sobel(src, dst4, -1, 1, 0, 3, 1.0, 0.0, BORDER_CONSTANT);end = clock();std::cout << "4.opencv-sobel计算:" << end - start << std::endl;// 效果比较Mat findzero1 = dst2 != dst4; //方法一和方法二比较效果Mat findzero2 = dst2 != dst4; //方法二和方法三比较效果Mat findzero3 = dst2 != dst4; //方法二和方法四比较效果vector<cv::Point> veczero1;vector<cv::Point> veczero2;vector<cv::Point> veczero3;cv::findNonZero(findzero1, veczero1);cv::findNonZero(findzero2, veczero2);cv::findNonZero(findzero3, veczero3);int num1 = veczero1.size();int num2 = veczero2.size();int num3 = veczero3.size();std::cout << "方法一和方法二逐像素比较,像素不同个数:" << num1 << std::endl;std::cout << "方法二和方法三逐像素比较,像素不同个数:" << num2 << std::endl;std::cout << "方法二和方法四逐像素比较,像素不同个数:" << num3 << std::endl;system("pause");return 0;
}

计算结果显示,可分离核计算比常规计算快一倍左右,与OpenCV的sobel算子处理时间相当。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/98163.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

macOS通过钥匙串访问找回WiFi密码

如果您忘记了Mac电脑上的WiFi密码&#xff0c;可以通过钥匙串访问来找回它。具体步骤如下&#xff1a; 1.打开Mac电脑的“启动台”&#xff0c;然后在其他文件中找到“钥匙串访问”。 2.运行“钥匙串访问”应用程序&#xff0c;点击左侧的“系统”&#xff0c;然后在右侧找到…

三步搭建个人网站并发布上线【内网穿透】

三步搭建个人网站并发布上线【内网穿透】 文章目录 三步搭建个人网站并发布上线【内网穿透】前言一、在本地电脑上制作一个网站二、使用WordPress建立网站三、通过cpolar建立的数据隧道发布到公网上 前言 在这个个性飞扬的时代&#xff0c;每个人都希望拥有表现自我的平台&…

Springboot 实践(12)RabbitMq server 安装调试(Windows环境)

一、准备安装文件 1、下载Erlang 登录网站Downloads - Erlang/OTP&#xff0c;选择“Download Windows installer”&#xff0c;如下图所示&#xff1a; 弹出框中&#xff0c;选在下载保存地址&#xff0c;保存文件&#xff0c;如下图所示&#xff1a; 2、下载RabbitMQ 登录…

正版软件|Splashtop Personal 个人版桌面和移动远程控制软件

Splashtop Personal 个人版 - 从平板电脑、智能手机或另一台计算机轻松远程访问 Mac 或 Windows PC 最多可达 5 台设备。在本地网络上免费使用 Splashtop Personal *即可从舒适的沙发或卧室访问家用计算机。 通过订阅 Anywhere Access Pack&#xff0c;可以从 Internet 上的任何…

华为Mate 60系列发售,北斗卫星通信技术进一步深入大众消费市场

近日&#xff0c;华为Mate 60系列手机在没有举办发布会的情况下在官方商城突然上架开售&#xff0c;人气火爆。 值得一提的是&#xff0c;华为Mate60 Pro支持卫星通话&#xff0c;无地面网络时&#xff0c;也能拨打和接听卫星电话&#xff0c;还可自由编辑卫星消息。华为 Mate6…

word中标题及公式自动编号

word中公式自动编号 1. 实现目标2. 详细步骤2.1 添加自动编号功能2.2 输入标题并编号2.3 新建公式2.3.1 编辑公式2.3.4 公式编号的交叉引用2.3.5 公式位置变动以及更新正文中的编号 在word中自动编号公式一直是一个老大难问题&#xff0c;现在通过总结网友们提供的方法&#xf…

【深入解析spring cloud gateway】07 自定义异常返回报文

Servlet的HttpResponse对象&#xff0c;返回响应报文&#xff0c;一般是这么写的&#xff0c;通过输出流直接就可以将返回报文输出。 OutputStream out response.getOutputStream(); out.write("输出的内容"); out.flush();在filter中如果发生异常&#xff08;例如…

linux 下安装chrome 和 go

1. 安装google-chrome 1.1 首先下载google-chrome.deb安装包 之后 安装 gdebi包 sudo apt install gdebi 1.2 安装所要安装的软件 sudo gdebi code_1.81.1-1691620686_amd64.deb 1.3 解决Chrome无法启动问题 rootubuntu:~/Downloads# whereis google-chrome google-chrome…

java八股文面试[JVM]——JVM性能优化

JVM性能优化指南 JVM常用命令 jps 查看java进程 The jps command lists the instrumented Java HotSpot VMs on the target system. The command is limited to reporting information on JVMs for which it has the access permissions. jinfo &#xff08;1&#xff09;实时…

我国元宇宙专利申请位列全球靠前,UTONMOS元宇宙游戏体验再升级

中青网报道 近日&#xff0c;2023年服贸会数字贸易发展趋势和前沿高峰论坛举办并发布了《中国元宇宙产业发展趋势洞察》报告。报告指出我国元宇宙相关专利申请量位列全球第二。 元宇宙是虚拟世界和现实世界融合的载体&#xff0c;正成为驱动数字经济发展和助力数字中国建设的重…

OpenCV基础知识(10)— 人脸识别(人脸跟踪、眼睛跟踪、行人跟踪、车牌跟踪和人脸识别)

前言&#xff1a;Hello大家好&#xff0c;我是小哥谈。人脸识别是基于人的脸部特征信息进行身份识别的一种生物识别技术&#xff0c;也是计算机视觉重点发展的技术。机械学习算法诞生之后&#xff0c;计算机可以通过摄像头等输入设备自动分析图像中包含的内容信息&#xff0c;随…

AcWing 788. 逆序对的数量(归并排序)

基本思想 归并排序是用分治思想&#xff0c;分治模式在每一层上有三个步骤&#xff1a; &#xff08;1&#xff09;分解&#xff1a;将n个元素分解成n/2个元素的子序列。 &#xff08;2&#xff09;解决&#xff1a;用合并排序法对两个子序列递归排序。 &#xff08;3&…