Find local maximum in 1D & 2D Mat
How can I find local maximum in the 1D & 2D Mat?
How can I find local maximum in the 1D & 2D Mat?
To find a local maximum in the 2d Mat in the first dilate Mat then subtract from original image.
Red points are local maximum.
code:
vector<Point> bhContoursCenter(const vector<vector<Point>>& contours,bool centerOfMass,int contourIdx=-1)
{
vector<Point> result;
if (contourIdx > -1)
{
if (centerOfMass)
{
Moments m = moments(contours[contourIdx],true);
result.push_back( Point(m.m10/m.m00, m.m01/m.m00));
}
else
{
Rect rct = boundingRect(contours[contourIdx]);
result.push_back( Point(rct.x + rct.width / 2 ,rct.y + rct.height / 2));
}
}
else
{
if (centerOfMass)
{
for (int i=0; i < contours.size();i++)
{
Moments m = moments(contours[i],true);
result.push_back( Point(m.m10/m.m00, m.m01/m.m00));
}
}
else
{
for (int i=0; i < contours.size(); i++)
{
Rect rct = boundingRect(contours[i]);
result.push_back(Point(rct.x + rct.width / 2 ,rct.y + rct.height / 2));
}
}
}
return result;
}
vector<Point> bhFindLocalMaximum(InputArray _src,int neighbor=2){
Mat src = _src.getMat();
Mat peak_img = src.clone();
dilate(peak_img,peak_img,Mat(),Point(-1,-1),neighbor);
peak_img = peak_img - src;
Mat flat_img ;
erode(src,flat_img,Mat(),Point(-1,-1),neighbor);
flat_img = src - flat_img;
threshold(peak_img,peak_img,0,255,CV_THRESH_BINARY);
threshold(flat_img,flat_img,0,255,CV_THRESH_BINARY);
bitwise_not(flat_img,flat_img);
peak_img.setTo(Scalar::all(255),flat_img);
bitwise_not(peak_img,peak_img);
vector<vector<Point>> contours;
findContours(peak_img,contours,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_SIMPLE);
return bhContoursCenter(contours,true);
}
To find a local maximum in the 1d Mat I've used the derivatives.
Red lines are local maximum.
typedef struct BhRange
{
int pos1;
int pos2;
int size()
{
return pos2 - pos1 +1;
}
}BhRange;
typedef struct BhPeekInfo
{
int pos;
int left_size;
int right_size;
float value;
}BhPeekInfo;
typedef vector<BhPeekInfo> BhPeekInfos;
BhPeekInfo bhPeekInfo(int pos,int left_size,int
right_size,float value)
{
BhPeekInfo result;
result.pos = pos;
result.left_size = left_size;
result.right_size = right_size;
result.value = value;
return result;
}
BhPeekInfos bhFindPeeks2(InputArray _src,int
window_size)
{
Mat src = _src.getMat();
//#define _BH_SHOW_IMAGE
#ifdef _BH_SHOW_IMAGE
CvMat *slope_mat = cvCloneMat(src);
float *slope_p = slope_mat->data.fl;
#endif
Mat src2 = src.reshape(1,1);
float *src_p = (float*) src2.ptr<float>(0);
int size = window_size / 2;
int thr = 20;
BhRange up_hill ,down_hill;
BhPeekInfos result;
int pre_state = 0;
int i = size;
while ( i < src2.cols - size)
{
float cur_state = src_p[i + size] - src_p[i - size];
if (cur_state > 0)
cur_state = 2;
else if (cur_state < 0)
cur_state = 1;
else cur_state = 0;
#ifdef _BH_SHOW_IMAGE
slope_p[i] = cur_state;
#endif
if (pre_state == 0 && cur_state == 2)
up_hill.pos1 = i;
else if (pre_state == 2 && cur_state == 1)
{
up_hill.pos2 = i -1;
down_hill.pos1 = i;
}
if ((pre_state == 1 && cur_state == 2) || (pre_state == 1
&& cur_state == 0))
{
down_hill.pos2 = i-1;
int max_pos = up_hill.pos2;
if ( src_p[up_hill.pos2] < src_p[down_hill.pos1])
max_pos = down_hill.pos1;
BhPeekInfo peek_info = bhPeekInfo(max_pos,up_hill.size(),down_hill.size(),src_p[max_pos]);
result.push_back(peek_info);
}
i++;
pre_state = (int)cur_state;
}
#ifdef _BH_SHOW_IMAGE
IplImage *view_img = bhDrawProjection(slope_mat,BH_HORZ_DIRECT,100,BH_DRAW_BAR);
cvShowImage("slope image",view_img);
cvWaitKey(0);
cvReleaseImage(&view_img);
cvReleaseMat(&slope_mat);
#undef _BH_SHOW_IMAGE
#endif
return result;
}
vector<int> bhGetLocalMaximum2(InputArray
_src,int smooth_size =9,int neighbor_size =3,float peek_per=0.5)
{
Mat src = _src.getMat().clone();
//#define _BH_SHOW_IMAGE
#ifdef _BH_DEBUG
#define _BH_SHOW_IMAGE
#endif
vector<int> result;
GaussianBlur(src,src ...
(more)Asked: 2014-02-09 01:55:44 -0600
Seen: 14,913 times
Last updated: Feb 09 '14
http://courses.csail.mit.edu/6.006/spring11/lectures/lec02.pdf. Hope it's relevant to what you need.