2通道复数Mat的共轭
代码如下
cv::Mat conj4mat(cv::Mat src) {
if (src.channels() != 2) {
std::cout << "func CONJ4MAT : channels parameters error!" << std::endl;
return Mat();
}
int cols = src.cols;// 表示x轴
int rows = src.rows;// 表示y轴
cv::Mat result = cv::Mat::zeros(cv::Size(cols, rows), CV_32FC2);
/*核心思想: 将图像按照每一行的顺序,进行展开,成为一个长的向量。 例如一个Size(640,480)的图像,展开后,向量的长度为 640*480 */
std::vector<cv::Mat> channels;//用于存放实部和虚部,channels[0]存放的是实部,channels[1]存放的是虚部
std::complex<double>* conj4mat = new std::complex<double>[cols * rows]; //用于存放展开后的复数向量
std::complex<double> temp;
cv::split(src, channels);
int k = 0;//用于存放数据到复数数组里的索引,其最大值应该为 rows * cols
double real = 0, imag = 0;
//前向计算过程
for (size_t i = 0; i < cols; i++) {
for (size_t j = 0; j < rows; j++) {
real = channels[0].at<float>(j, i);
imag = channels[1].at<float>(j, i);
temp = std::complex<double>(real, imag);
conj4mat[k] = temp;
k++;
}
}
k = 0;
std::complex<double> middle;
//反向释放数据到Mat
for (size_t i = 0; i < cols; i++) {
for (size_t j = 0; j < rows; j++) {
middle = std::conj(conj4mat[k]);
real = middle.real();
imag = middle.imag();
channels[0].at<float>(j, i) = real;
channels[1].at<float>(j, i) = imag;
k++;
}
}
// 将求得的结果合并为一个Mat
merge(channels, result);
return result;
}
两个复数Mat的直积
cv::Mat cmplxMul(cv::Mat m1, cv::Mat m2) {
//assert(m1.rows != m2.rows,"相乘矩阵的维度不一致");
//assert(m1.cols != m2.cols,"相乘矩阵的维度不一致");
int rows = m1.rows;//矩阵的行数以及列数
int cols = m1.cols;
cv::Mat result = cv::Mat::zeros(rows, cols,CV_32FC2);
//用于存放实部[0]以及虚部[1]
vector<Mat> channels_m1;
vector<Mat> channels_m2;
vector<Mat> channels_result;
split(m1, channels_m1);
split(m2, channels_m2);
split(result, channels_result);
//用于将矩阵形式的复数转换乘向量
vector<std::complex<float>> complex_result;
std::complex<float> m1_c;
std::complex<float> m2_c;
//分解m1以及m2中的复数
for (size_t i = 0; i < rows; i++) {
for (size_t j = 0; j < cols; j++) {
m1_c = std::complex<float>(
channels_m1[0].at<float>(i, j),
channels_m1[1].at<float>(i, j));
m2_c = std::complex<float>(
channels_m2[0].at<float>(i, j),
channels_m2[1].at<float>(i, j));
complex_result.push_back(m1_c * m2_c);
}
}
int k = 0;
//反向释放数据到Mat
for (size_t i = 0; i < rows; i++) {
for (size_t j = 0; j < cols; j++) {
channels_result[0].at<float>(i, j) = complex_result[k].real();
channels_result[1].at<float>(i, j) = complex_result[k].imag();
k++;
}
}
merge(channels_result, result);
return result;
}
两个复数Mat的对应位相除
cv::Mat cmplxDivision(cv::Mat m1, cv::Mat m2) {
//assert(m1.rows != m2.rows,"相乘矩阵的维度不一致");
//assert(m1.cols != m2.cols,"相乘矩阵的维度不一致");
int rows = m1.rows;//矩阵的行数以及列数
int cols = m1.cols;
cv::Mat result = cv::Mat::zeros(rows, cols, CV_32FC2);
//用于存放实部[0]以及虚部[1]
vector<Mat> channels_m1;
vector<Mat> channels_m2;
vector<Mat> channels_result;
split(m1, channels_m1);
split(m2, channels_m2);
split(result, channels_result);
//用于将矩阵形式的复数转换乘向量
vector<std::complex<float>> complex_result;
std::complex<float> m1_c;
std::complex<float> m2_c;
//分解m1以及m2中的复数
for (size_t i = 0; i < rows; i++) {
for (size_t j = 0; j < cols; j++) {
m1_c = std::complex<float>(
channels_m1[0].at<float>(i, j),
channels_m1[1].at<float>(i, j));
m2_c = std::complex<float>(
channels_m2[0].at<float>(i, j),
channels_m2[1].at<float>(i, j));
complex_result.push_back(m1_c / m2_c);
}
}
int k = 0;
//反向释放数据到Mat
for (size_t i = 0; i < rows; i++) {
for (size_t j = 0; j < cols; j++) {
channels_result[0].at<float>(i, j) = complex_result[k].real();
channels_result[1].at<float>(i, j) = complex_result[k].imag();
k++;
}
}
merge(channels_result, result);
return result;
}