使用SVD(奇异值分解)将滤波核进行行列滤波核的拆分,来减少滤波时计算次数,从而加快滤波速度

C++/OpenCV

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main(int argc, char** argv) {



	//Mat raw_mat = (Mat_ <float>(3, 3) << 1, 3, 4,
	//	2, 6, 2,
	//	5, 4, 3);

	//cout << "raw_mat = " << endl;
	//cout << raw_mat << endl;


	//Mat kernel22222 = (Mat_<char>(3, 3) << 0, -1, 0,
	//	-1, 5, -1,
	//	0, -1, 0);
	//Mat res1,res2, res3;
	//filter2D(raw_mat, res1, CV_32F, kernel22222, Point(-1, -1), 0, BORDER_DEFAULT);
	//cout << "res1 = " << endl;
	//cout << res1 << endl;



	//Mat kernel22223 = (Mat_<float>(1, 3) << 1, 2.5, 2);
	//Mat kernel22224 = (Mat_<float>(3, 1) << 1, 2.1, 1);
	//filter2D(raw_mat, res2, CV_32F, kernel22223, Point(-1, -1), 0, BORDER_DEFAULT);
	//filter2D(res2, res3, CV_32F, kernel22224, Point(-1, -1), 0, BORDER_DEFAULT);
	//cout << "res2 = " << endl;
	//cout << res2 << endl;
	//cout << "res3 = " << endl;
	//cout << res3 << endl;



	Mat outImg1, outImg2, outImg3, outImg4, outImg5;



	Mat src = imread("E:/1.png", IMREAD_COLOR);

	if (src.empty()) {
		printf("image is empty!!!");
		return -1;
	}
//	imshow("src", src);



	//Ksize: 滤波器的尺寸
	//Sigma : 高斯函数的标准差
	//Theta : 高斯函数
	//Lambd : 余弦函数的波长
	//Gamma : 高斯函数的宽高比,因为是二维高斯函数
	//Psi: 余弦函数的相位
	cv::Mat kernel;
	kernel = cv::getGaborKernel(cv::Size(3, 3), 40, 0, 5, 0.5, 0);
	cout << kernel << endl;
	//kernel = cv::getGaussianKernel(3, 1, CV_32F);
	//kernel = (Mat_<float>(3, 3) << 0, -1, 0,
	//	-1, 8, -1,
	//	0, -1, 0);

	std::cout << "kernel: " << kernel << std::endl;
	//filter2D(src, outImg1, CV_32F, kernel, Point(-1, -1), 0, BORDER_DEFAULT);
	//imshow("outImg", outImg1);
	//Mat kernel2 = (Mat_<float>(3, 3) << 0, -1, 0,
	//	-1, 5, -1,
	//	0, -1, 0);
	filter2D(src, outImg2, CV_32F, kernel, Point(-1, -1), 0, BORDER_DEFAULT);
	imshow("outImg2", outImg2);


	//Mat kernel_row = (Mat_<char>(1, 3) << 0, 1, 0);
	//filter2D(src, outImg3, CV_32F, kernel_row, Point(-1, -1), 0, BORDER_DEFAULT);
	//imshow("outImg3", outImg3);

	//Mat kernel_col = (Mat_<char>(3, 1) << 0, 1, 0);
	//filter2D(src, outImg4, CV_32F, kernel_col, Point(-1, -1), 0, BORDER_DEFAULT);
	//imshow("outImg4", outImg4);

	 SVD分解
	SVD svd(kernel);
	// 列向量(列形式)
	Mat U = svd.u;
	cout << "U = " << endl;
	cout << U << endl;
	Mat colOne = U.colRange(0, 1).clone();
	cout << "colOne = " << endl;
	cout << colOne << endl;
	// 行向量(行形式)
	Mat V = svd.vt;
	cout << "V = " << endl;
	cout << V << endl;
	Mat rowOne = V.rowRange(0, 1).clone();
	cout << "rowOne = " << endl;
	cout << rowOne << endl;
	// 奇异值
	Mat D = svd.w;
	cout << "D = " << endl;
	cout << D << endl;
	float Gama =1.89;
	// 行卷积
	Mat  resImg_row;
	// transpose(rowOne, rowOneT);
	filter2D(src, resImg_row, CV_32F, rowOne* Gama, Point(-1, -1), 0, BORDER_DEFAULT);
	// 列卷积
	Mat resImg_col;
	//transpose(rowOne, rowOneT);
	filter2D(resImg_row, resImg_col, CV_32F, colOne, Point(-1, -1), 0, BORDER_DEFAULT);
	imshow("resImg_col: ", resImg_col);
	cout << " outImg2:  "<< outImg2.at<float>(0, 0) << endl;
	cout << " resImg_col: " << resImg_col.at<float>(0, 0) << endl;
	waitKey(0);
	destroyAllWindows();
	return 0;
}




Python

import numpy as np
import scipy
import scipy.ndimage
from numpy import linalg as la
from numpy import *
img = [[255, 255, 255],[255, 255,255],[255, 255, 255]]
myl = [[0, -1, 0],[-1, 8, -1],[0, -1, 0]]
# myl = [[4, 0, 5], [0, 0, 5]]
myMat = mat(myl)
U, Sigma, VT = la.svd(myMat)
U, Sigma, VT = np.linalg.svd(myMat)
print("U:", U)
print("Sigma:", Sigma)
print("VT:", VT)
print(U[:, 0, np.newaxis])
print(VT[0,:, np.newaxis])

# x=np.array(U[:,0]).reshape(3,1) #等价于 x=np.arange(0,5)
# y=np.array(VT[0]).reshape(1,3)
# print(x)
# print(y)
# print("Mat:",np.dot(x,y)*Sigma[0])
final_res2 = scipy.ndimage.convolve(img, myl)
print("final res2:",final_res2)
final_res = 0
for i in range(1):
    final_res += Sigma[i] * scipy.ndimage.convolve(scipy.ndimage.convolve(img, U[:, i, np.newaxis]),
                                                  np.transpose(VT[i, :, np.newaxis]))
print("final res:",final_res)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值