FT(IG)显著+分割+Surf识别笔记(一)
来源:互联网 发布:如何复制知乎的文字 编辑:程序博客网 时间:2024/05/08 16:41
FT(IG)显著+分割+Surf识别笔记
- FT代码注释
- Mean Shift分割代码“
- Surf部分`
代码块
//FT显著#include "Saliency.h"#include "cmath"//这只是显著部分,要自己写个main函数,读取图像,还要转成灰度图,太累了不复制了> void Saliency::RGB2LAB( const vector<unsigned int>& ubuff, vector<double>& lvec, vector<double>& avec, vector<double>& bvec){//这部分是求RGB转到LAB的过程,要经过转XYZ的过程 int sz = int(ubuff.size()); lvec.resize(sz); avec.resize(sz); bvec.resize(sz); for( int j = 0; j < sz; j++ ) { int r = (ubuff[j] >> 16) & 0xFF; int g = (ubuff[j] >> 8) & 0xFF; int b = (ubuff[j] ) & 0xFF; double xval = 0.412453 * r + 0.357580 * g + 0.180423 * b; double yval = 0.212671 * r + 0.715160 * g + 0.072169 * b; double zVal = 0.019334 * r + 0.119193 * g + 0.950227 * b; xval /= (255.0 * 0.950456); yval /= 255.0; zVal /= (255.0 * 1.088754); double fX, fY, fZ; double lval, aval, bval; if (yval > 0.008856) { fY = pow(yval, 1.0 / 3.0); lval = 116.0 * fY - 16.0; } else { fY = 7.787 * yval + 16.0 / 116.0; lval = 903.3 * yval; } if (xval > 0.008856) fX = pow(xval, 1.0 / 3.0); else fX = 7.787 * xval + 16.0 / 116.0; if (zVal > 0.008856) fZ = pow(zVal, 1.0 / 3.0); else fZ = 7.787 * zVal + 16.0 / 116.0; aval = 500.0 * (fX - fY)+128.0; bval = 200.0 * (fY - fZ)+128.0; lvec[j] = lval; avec[j] = aval; bvec[j] = bval; }}/// 高斯平滑void Saliency::GaussianSmooth( const vector<double>& inputImg, const int& width, const int& height, const vector<double>& kernel, vector<double>& smoothImg){ int center = int(kernel.size())/2; int sz = width*height; smoothImg.clear(); smoothImg.resize(sz); vector<double> tempim(sz); int rows = height; int cols = width; // Blur in the x direction. {int index(0); for( int r = 0; r < rows; r++ ) { for( int c = 0; c < cols; c++ ) { double kernelsum(0); double sum(0); for( int cc = (-center); cc <= center; cc++ ) { if(((c+cc) >= 0) && ((c+cc) < cols)) { sum += inputImg[r*cols+(c+cc)] * kernel[center+cc]; kernelsum += kernel[center+cc]; } } tempim[index] = sum/kernelsum; index++; } }} // Blur in the y direction. {int index = 0; for( int r = 0; r < rows; r++ ) { for( int c = 0; c < cols; c++ ) { double kernelsum(0); double sum(0); for( int rr = (-center); rr <= center; rr++ ) { if(((r+rr) >= 0) && ((r+rr) < rows)) { sum += tempim[(r+rr)*cols+c] * kernel[center+rr]; kernelsum += kernel[center+rr]; } } smoothImg[index] = sum/kernelsum; index++; } }}}/// GetSaliencyMap////// Outputs a saliency map with a value assigned per pixel. The values are/// normalized in the interval [0,255] if normflag is set true (default value).void Saliency::GetSaliencyMap( const vector<unsigned int>& inputimg, const int& width, const int& height, vector<double>& salmap, const bool& normflag) { int sz = width*height; salmap.clear(); salmap.resize(sz); vector<double> lvec(0), avec(0), bvec(0); RGB2LAB(inputimg, lvec, avec, bvec); // Obtain Lab average values double avgl(0), avga(0), avgb(0); {for( int i = 0; i < sz; i++ ) { avgl += lvec[i]; avga += avec[i]; avgb += bvec[i]; }} avgl /= sz; avga /= sz; avgb /= sz; vector<double> slvec(0), savec(0), sbvec(0); // The kernel can be [1 2 1] or [1 4 6 4 1] as needed. // The code below show usage of [1 2 1] kernel. vector<double> kernel(0); //高斯滤波的核是[1,2,1] kernel.push_back(1.0); kernel.push_back(2.0); kernel.push_back(1.0); GaussianSmooth(lvec, width, height, kernel, slvec); //高斯平滑 GaussianSmooth(avec, width, height, kernel, savec); GaussianSmooth(bvec, width, height, kernel, sbvec); {for( int i = 0; i < sz; i++ ) //得到的结果高斯平滑减去原始图像的均值,如果有低频信号通过图像平滑最后减去均值就没有响应了,相反高频部分,通过平滑残留了高频响应减去了均值还是有响应,这部分我们认为是显著区域,最后返回结果 { salmap[i] = (slvec[i]-avgl)*(slvec[i]-avgl) + (savec[i]-avga)*(savec[i]-avga) + (sbvec[i]-avgb)*(sbvec[i]-avgb); }}//以上就是FT求图像显著图的主要代码 if( true == normflag )//这是归一化,就是每个图像像素值都缩小为[0-1]的函数。函数为Normalize { vector<double> normalized(0); Normalize(salmap, width, height, normalized); swap(salmap, normalized); }}
//分割代码
#include "stdafx.h" //stdafx.h要自己建一个这样的库// meanshift_segmentation.cpp : 定义控制台应用程序的入口点。 // #include"opencv2/core/core.hpp" #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include "iostream" #pragma comment(lib,"opencv_highgui2413d.lib") #pragma comment(lib,"opencv_core2413d.lib") #pragma comment(lib,"opencv_imgproc2413d.lib") using namespace cv;using namespace std;Mat src, dst;int spatialRad, colorRad, maxPryLevel;int main(int argc, uchar* argv[]){ int maxPyrLevel = 3; //金字塔层数 Mat res; double duration = static_cast<double>(getTickCount()); Mat img = imread("E:/Codes/CprimerPlus/chapter13/分割/31.jpg"); //读图路径 //路径要加引号,一般程序出错最有可能是路径问题,有绝对路径和相对路径之分,绝对路径:/ //相对路径:可直接引用程序下的图片 int spatialRad = 4; //值越大时间会越长 int colorRad = 30; //值越大图像会分割的区域数越小 pyrMeanShiftFiltering(img, res, spatialRad, colorRad, maxPyrLevel); imshow("res", res); RNG rng = theRNG(); Mat mask(res.rows + 2, res.cols + 2, CV_8UC1, Scalar::all(0)); //掩模 for (int y = 0; y < res.rows; y++) { for (int x = 0; x < res.cols; x++) { if (mask.at<uchar>(y + 1, x + 1) == 0) //非0处即为1,表示已经经过填充,不再处理 { //Scalar newVal(rng(256), rng(256), rng(256)); //floodFill(res, mask, Point(x, y), newVal, 0, Scalar::all(5), Scalar::all(5)); //执行漫水填充 } } } imshow("meanShift图像分割", res); imwrite("result.jpg", res); duration = ((double)getTickCount() - duration) / getTickFrequency(); cout << "运行时间" << duration << "秒" << endl; waitKey(); return 0; }
Surf部分没什么好写的,基本是OPENCV3书上原装程序,要说所有程序完全是我自己写的只有得到分割后将它扣出来,其他都是主程序,自己修修小数据
#include "stdafx.h" #include "opencv2/core/core.hpp"#include "opencv2/imgproc/imgproc.hpp"#include "opencv2/highgui/highgui.hpp"#include "opencv2/opencv.hpp"#include "iostream"using namespace cv;using namespace std;int main(int argc, char** argv){ Mat binary; Mat result = imread("2.jpg", 0);//这里0表示读取图像并转为灰度图即[0-255] Mat tongji; threshold(result, binary, 50, 255, CV_THRESH_BINARY);//阀值化,固定阀值吧,不是自适应的。 //里面的参数分别代表;输入图像;输出图像;最低阀值,往上为1,下为0;这个图像里像素值的最大///值;二值化的表示,也有其他表示方法 Mat element = getStructuringElement(MORPH_RECT, Size(50, 50));//膨胀操作的一个自定义核 Mat out; double maxArea = 0; vector<cv::Point> maxContour; dilate(binary, out, element);//膨胀。一般写前面三个参数,后面有默认的 vector<vector<cv::Point>> contours;//vector是结构体或者容器 findContours(out, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);//寻找轮廓 //里面参数:输入;输出;检测轮廓类别,这个是检测最外围轮廓(还有所有轮廓并放list中,提取所有轮廓//并组织为双层结构,最后一个是提取轮廓建立网状结构);获取轮廓的每个像素。 for (int i = 0; i < contours.size(); i++) { double area = contourArea(contours[i]);//轮廓面积 if (area > maxArea) { maxArea = area; maxContour = contours[i]; } } Rect maxRect = boundingRect(maxContour);//求最大轮廓面积,并返回轮廓的最大矩形 Mat original = imread("1.jpg");//原图 Mat gray = result; Mat hole(gray.size(), CV_8U, Scalar(0));//建立模版方便抠图所用的转换,与原图大小一样 rectangle(hole, Rect(maxRect.x, maxRect.y, maxRect.width, maxRect.height), Scalar(255, 255, 255), -1, 1, 0);//刚刚矩形的位置,在模版相同的矩形位置变白色 double a = maxRect.x; double b = maxRect.y; double c = maxRect.width; double d = maxRect.height; printf("左上点x:%f\n", a); printf("左上点y:%f\n", b); printf("宽:%f\n", c); printf("高:%f\n", d);//显示矩形的位置数据 namedWindow("My hole"); imshow("My hole", hole); Mat crop(original.rows, original.cols, CV_8UC3); original.copyTo(crop, hole);//将原图像拷贝进遮罩图层 namedWindow("My warpPerspective"); imshow("My warpPerspective", crop); imwrite("result.jpg", crop); imshow("image", result); waitKey(); return 0; }
阅读全文
0 0
- FT(IG)显著+分割+Surf识别笔记(一)
- FT(IG)显著+分割+Surf识别笔记(二)
- 图像局部显著性—点特征(SURF)
- 显著性检测文献阅读笔记之FT算法
- 显著性检测方法FT
- 图像显著性论文 (一)-----(三)
- Fault Tolerance(FT)
- MATLAB学习笔记 图像分割(一)
- Opencv图像识别从零到精通(35)---SURF
- SURF特征提取分析(一)
- 语音识别学习笔记(一)【概述】
- 学习笔记--车牌识别(一)
- Kaldi语音识别学习笔记(一)
- 显著性论文学习阶段总结(一)
- 显著性论文学习阶段总结(一)
- 关于视觉显著性检测的思考(一)
- 显著性论文学习阶段总结(一)
- 图像处理:显著性区域检测总结(一)
- 怎样在SQL SERVER中添加系统默认时间字段
- 分布式调用跟踪与监控实战
- Swift: 获取目录结构
- 基于Basys 2的VGA视频游戏——Running man
- 关于线程死锁的了解(LIUNX)
- FT(IG)显著+分割+Surf识别笔记(一)
- 基于caffe的鉴黄图片分类c++代码
- Qt的Model/View Framework解析
- C++/CLI:第一流的CLI语言
- 设计模式用前须知
- 2017年华为软件精英挑战赛初赛解题思路
- java汉子转拼音
- 十一、NG Validation表单验证插件
- Android Studio project和module的区别