投影波峰查找

波峰波谷算法

投影曲线实际上是一个一维的向量:

V=[v1,v2,…,vn]

其中 vi,i∈[1,2,…,N],代表图像在第 i行或列上的灰度累积。当然不仅仅是投影曲线, T也可以是某一事件中变量的观测值,我们需要研究这个变量的变化规律。

下面给出波峰与波谷的算法:

1,假投影曲线可以表示为 V=[v1,v2,…,vn]

2,计算V的一阶差分向量 DiffV:

Diffv(i)=V(i+1)−V(i),其中i∈1,2,…,N−1

3,对差分向量进行取符号函数运算, Trend=sign(Diffv),即遍历 Diffv,若 Diffv(i)大于0,则取1;如果小于0,则取-1,否则则值为0。

sign(x)={1  if  x>00  if  x=0−1  if  x<0

4,从尾部遍历 Trend向量,进行如下操作:

if Trend(i)=0Trend(i+1)0Trend(i)=1 if Trend(i)=0Trend(i+1)<0Trend(i)=1

5,对 Trend向量进行一阶差分运算,如同步骤2,得到 R=diff(Trend)

6,遍历得到的差分向量 R,如果 R(i)=−2,则 i+1为投影向量 V的一个峰值位,对应的峰值为 V(i+1);如果 R(i)=2,则 i+1为投影向量 V的一个波谷位,对应的波谷为 V(i+1)

下面我们来结合一个实际的向量值,给中中间结合的计算。

1, V=[−5,10,10,14,14,8,8,6,6,−3,2,2,2,2,−3]

它的曲线图像如下把示,图中红色圈标出了曲线的峰值,而绿字圈标出了图像的波谷位置。

image

2,计算 V的一阶差分,我们得到 Diff(V)=[15,0,4,0,,−6,0,−2,0,−9,5,0,0,0,−5]

3,对 Diffv进行取符号运算,得到向量 Trend=[1,0,1,0,−1,0,−1,0,−1,1,0,0,0,−1]

4,对 Trend作一次遍历,如步骤4。 Trend=[1,1,1,−1,−1,−1,−1,−1,−1,1,−1,−1,−1,−1]

5,对 Trend做一阶差分,得到向量 R=Diff(Trend)=[0,0,−2,,0,0,0,0,0,2,−2,0,0,0]

6,遍历向量 R,我们就得到了两个峰值点和一个波谷点。

算法原理

其实上述算法的核心思路非常简单,曲线的峰值点,满足一阶导数为0,并且满足二阶导数为负;而波谷点,则满足一阶导数为0,二阶导数为正。

在上面的算法里面,我们首先计算了一阶的导数 Diffv,然后我们将其符号化,是因为我们并不关心一阶导数的大小。

然后我们去看那些一阶层数为0的地方,我们发现,那些平台上的点,有些并不是波峰与波谷,然后很多处在上坡与下坡的路上,所以我们将它们的一阶导数设为与它们所在的坡面梯度方向相同。

最后我们再来计算二阶导数时,就会发现只要为2或者-2,所以曲线斜在这个点发生了变化,由正变负或由负变正。找到这些点,也就找到了原曲线中的波峰或波谷点。


代码实现:
#include<opencv2\highgui\highgui.hpp>
#include<opencv2\imgproc\imgproc.hpp>
#include<iostream>
#include<stdio.h>
#include<vector>
using namespace cv;
using namespace std;
void findpeak(Mat &srcImage, vector<int>& resultVec)
{
	Mat verMat;
	Mat resMat = srcImage.clone();

	
	int thresh = 130;
	int threshType = 0;
	
	
	const int maxVal = 255;
	
	threshold(srcImage, srcImage, thresh, maxVal, threshType);

	
	srcImage.convertTo(srcImage, CV_32FC1); 
	reduce(srcImage, verMat, 0, CV_REDUCE_SUM);
	float* iptr = (float*)verMat.data;
	vector<int> tempVec(verMat.cols - 1, 0);

	
	for (int i = 0; i < verMat.cols - 1; ++i, ++iptr)
	{
		if(*(iptr+1) - *iptr > 0)
		{
			tempVec[i] = 1;
		}
		else if (*(iptr + 1) - *iptr < 0)
		{
			tempVec[i] = -1;
		}
		else
		{
			tempVec[i] = 0;
		}
	}

	
	for (int i = tempVec.size() - 1; i >= 0; i--)
	{
		if (tempVec[i] == 0 && i == tempVec.size() - 1)
		{
			tempVec[i] = 1;
		}
		else if (tempVec[i] == 0)
		{
			if (tempVec[i + 1] >= 0)
				tempVec[i] = 1;
			else
				tempVec[i] = -1;
		}
	}

	
	for (vector<int>::size_type i = 0; i != tempVec.size() - 1; i++)
	{
		if (tempVec[i + 1] - tempVec[i] == -2)
		{
			resultVec.push_back(i + 1);
		}
	}

	
	for (int i = 0; i < resultVec.size(); i++)
	{
		cout << resultVec[i] << endl;
		for (int ii = 0; ii < resMat.rows; ++ii)
		{
			resMat.at<uchar>(ii, resultVec[i]) = 255;
		}
	}
	imshow("resMat", resMat);
}
int main()
{
	Mat image = imread("test.jpg");
	if (!image.data)
	{
		printf("could not load image...\n");
		return -1;
	}
	
	cvtColor(image, image, CV_BGR2GRAY);
	imshow("image", image);
	vector<int> resultVec;
	findpeak(image, resultVec);
	waitKey(0);
	return 0;
}

波峰的位置:
28 70 107 120 144 158 162 165 176 215

原图的灰度图:


效果图:

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Google Earth Engine是一个免费的云平台,用于存储、分析和可视化大量地理信息数据。其中,投影EPSG是一种重要的工具,用于确定地图投影坐标系和位置关系。在使用Google Earth Engine时,查找投影EPSG是十分必要的。 首先,在 Google Earth Engine中使用的地图可能不是统一的地图投影,这取决于数据源和应用场景。一些地图可能使用Web墨卡托投影(Web Mercator)的坐标系,这是谷歌地图默认所使用的坐标系,而其他的地图则使用其他的投影方式。因此,正确查找和理解投影EPSG代码,对于数据的使用和分析非常必要。 在Google Earth Engine中,查找投影EPSG可以通过以下步骤实现: 首先,在Google Earth Engine中创建一个新的代码块。接着,需要通过JavaScript语言指定一个影像或地图的变量,如下所示: var tif = ee.Image('ImageID'); 在给定变量后,可以使用projection()函数来列出该变量的投影信息,如下所示: var tif_projection = tif.projection(); print('Projection', tif_projection); 执行完上述代码块之后,即可在控制台中显示投影代码EPSG,例如: Projection: Projection({ "type": "Projection", "crs": "EPSG:4326", "transform": [1, 0, 0, 0, 1, 0], "units": "degrees", }) 其中,输出中的“crs”项即为投影的EPSG代码。此时,可以根据数据需要进行相应的处理和调整。 总的来说,Google Earth Engine的投影EPSG查找是数据分析和可视化中的一项基础技能。通过上述方法,可以方便的获得影像或地图的投影信息,从而更好的解析和使用数据。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值