今天看论文接触到一个新词—显著性检测,刚开始没想到是一个专业词汇,查了博客发现是一种极好的目标检测算法,可用于目标检测和定位,目标ROI区域粗分割,继而进行目标图像处理。
贴出原博客链接:OpenCV-python图像显著性检测算法
据说几种算法中FT算法比较好,所以只跑了C++版的代码。
**
解释:
**图像在频率域可以分成低频部分和高频部分。低频部分反映了图像的整体信息,如物体的轮廓,基本的组成区域。高频部分反映了图像的细节信息,如物体的纹理。显著性区域检测用到的更多的是低频部分的信息。在实际进行计算时,FT方法使用窗口5*5的高斯平滑来实现对最高频的舍去。
步骤:
1、对图像进行 5*5 的高斯平滑。
2、转换颜色空间。RGB颜色空间转换为CIELAB颜色空间。
3、计算整幅图片的 l、a、b的平均值。
4、按照算法中的公式,计算每个像素l、a、b值同图像三个l、a、b均值的欧氏距离。得到显著图
5、归一化。图像中每个像素的显著值除以最大的那个显著值。得到最终的显著图。
代码:
感谢博主代码分享:
/*===========================================================================
Copyright@hitzym, Harbin Institute of Technology
Date:Apr,13,2018
Contact:zhenyumei1995@163.com
blog: https://blog.csdn.net/yinhuan1649
===========================================================================*/
#include <iostream>
#include <opencv2/opencv.hpp>
#include <fstream> using namespace cv;
using namespace std;void writeMatToFile(cv::Mat& m, const char* filename) //把矩阵写入txt文件
{std::ofstream fout(filename);if (!fout){std::cout << "File Not Opened" << std::endl;return;}for (int i = 0; i<m.rows; i++){for (int j = 0; j<m.cols; j++){fout << m.at<double>(i, j) << "\t";}fout << std::endl;}fout.close();
}int main() {Mat srcimg, grgbimg, labimg;srcimg = imread("D:/images/tool_3.jpg");int height = srcimg.rows;int width = srcimg.cols;GaussianBlur(srcimg, srcimg, Size(3, 3), 0, 0, BORDER_REFLECT); // 高斯模糊cvtColor(srcimg, labimg, COLOR_BGR2Lab); //转到lab空间cv:Scalar tempVal = cv::mean(labimg); //求各通道均值double lmean = tempVal.val[0];double amean = tempVal.val[1];double bmean = tempVal.val[2];Mat salientMap = Mat::zeros(height, width, CV_64F); //定义显著图,因为是double类型,所以在这里初始化类型为CV_64Ffor (int i = 0; i < height; i++) {for (int j = 0; j < width; j++) {//显著值计算,对应matlab代码中sm = (l-lm).^2 + (a-am).^2 + (b-bm).^2;salientMap.at<double>(i, j) = ((double)labimg.at<Vec3b>(i, j)[0] - lmean)*((double)labimg.at<Vec3b>(i, j)[0] - lmean)+ ((double)labimg.at<Vec3b>(i, j)[1] - amean)*((double)labimg.at<Vec3b>(i, j)[1] - amean)+ ((double)labimg.at<Vec3b>(i, j)[2] - bmean)*((double)labimg.at<Vec3b>(i, j)[2] - bmean);}}//double max, min;//cv::Point min_loc, max_loc;//cv::minMaxLoc(salientMap, &min, &max, &min_loc, &max_loc);//求mat中最值//cout << "max:"<< max << endl;//for (int i = 0; i < salientMap.rows; i++)//{// for (int j = 0; j < salientMap.cols; j++)// {// salientMap.at<double>(i, j) = salientMap.at<double>(i, j) / max;// }//}normalize(salientMap, salientMap, 1.00, 0.00, NORM_MINMAX); // 1值归一化writeMatToFile(salientMap, "F:\\test.txt");cout << "yes!!" << endl;//cout << "salientMap:" << salientMap << endl;imshow("src", srcimg);imshow("salientMap:", salientMap);cout << salientMap.channels() << endl;waitKey();system("pause");return 0;
}