OpenCV-计算自然对数cv::log
Posted 翟大宝Steven
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenCV-计算自然对数cv::log相关的知识,希望对你有一定的参考价值。
函数原型
void log(InputArray src, OutputArray dst);
参数说明
- InputArray类型的src,输入图像,如Mat类型。
- OutputArray类型的dst,输出的对数化图像。
测试代码
#include<iostream>
#include<opencv2/opencv.hpp>
#include<ctime>
using namespace std;
using namespace cv;
void fftshift(cv::Mat &plane0, cv::Mat &plane1);
int main(void)
{
Mat test = imread("test.jpg", 0);
test.convertTo(test, CV_32FC1);
//创建通道,存储dft后的实部与虚部(CV_32F,必须为单通道数)
cv::Mat plane[] = { test.clone(), cv::Mat::zeros(test.size() , CV_32FC1) };
cv::Mat complexIm;
cv::merge(plane, 2, complexIm); // 合并通道 (把两个矩阵合并为一个2通道的Mat类容器)
cv::dft(complexIm, complexIm, 0); // 进行傅立叶变换,结果保存在自身
// 分离通道(数组分离)
cv::split(complexIm, plane);
// 以下的操作是频域迁移
fftshift(plane[0], plane[1]);
// 计算幅值
cv::Mat mag,mag_log,mag_nor,mag_log_nor;
cv::magnitude(plane[0], plane[1], mag);
// 幅值对数化:log(1+m),便于观察频谱信息
mag += Scalar::all(1);
cv::log(mag, mag_log);
cv::normalize(mag, mag_nor, 1,0, NORM_MINMAX);
cv::normalize(mag_log, mag_log_nor, 1, 0, NORM_MINMAX);
cv::Mat BLUR;
// 再次搬移回来进行逆变换
fftshift(plane[0], plane[1]);
cv::merge(plane, 2, BLUR); // 实部与虚部合并
cv::idft(BLUR, BLUR); // idft结果也为复数
BLUR = BLUR / BLUR.rows / BLUR.cols;
cv::split(BLUR, plane);//分离通道,主要获取通道
imshow("original", test / 255);
imshow("result", plane[0] / 255);
waitKey(0);
system("pause");
return 0;
}
// fft变换后进行频谱搬移
void fftshift(cv::Mat &plane0, cv::Mat &plane1)
{
// 以下的操作是移动图像 (零频移到中心)
int cx = plane0.cols / 2;
int cy = plane0.rows / 2;
cv::Mat part1_r(plane0, cv::Rect(0, 0, cx, cy)); // 元素坐标表示为(cx, cy)
cv::Mat part2_r(plane0, cv::Rect(cx, 0, cx, cy));
cv::Mat part3_r(plane0, cv::Rect(0, cy, cx, cy));
cv::Mat part4_r(plane0, cv::Rect(cx, cy, cx, cy));
cv::Mat temp;
part1_r.copyTo(temp); //左上与右下交换位置(实部)
part4_r.copyTo(part1_r);
temp.copyTo(part4_r);
part2_r.copyTo(temp); //右上与左下交换位置(实部)
part3_r.copyTo(part2_r);
temp.copyTo(part3_r);
cv::Mat part1_i(plane1, cv::Rect(0, 0, cx, cy)); //元素坐标(cx,cy)
cv::Mat part2_i(plane1, cv::Rect(cx, 0, cx, cy));
cv::Mat part3_i(plane1, cv::Rect(0, cy, cx, cy));
cv::Mat part4_i(plane1, cv::Rect(cx, cy, cx, cy));
part1_i.copyTo(temp); //左上与右下交换位置(虚部)
part4_i.copyTo(part1_i);
temp.copyTo(part4_i);
part2_i.copyTo(temp); //右上与左下交换位置(虚部)
part3_i.copyTo(part2_i);
temp.copyTo(part3_i);
}
测试效果
从上图可以看出,未对数处理的图像几乎看不出什么规律,这是因为频谱信息中数据变化非常大,对数化是为了让数值的剧烈变化变得平滑,进而便于观察数据的规律和隐藏的信息。
log对数化是图像处理常用的操作哦~
如果文章帮助到你了,可以点个赞让我知道,我会很快乐~加油!
以上是关于OpenCV-计算自然对数cv::log的主要内容,如果未能解决你的问题,请参考以下文章