You can solve it by projection.
code :
#define BH_HORZ_DIRECT 100
#define BH_VERT_DIRECT 101
#define BH_BOTH_DIRECT 102
#define BH_LIMIT_POS1 0
#define BH_LIMIT_POS2 1
#define BH_LIMIT_SIZE 2
#define BH_LIMIT_SUM 3
#define BH_LIMIT_SIZE_MIN 4
#define BH_LIMIT_SIZE_MAX 5
typedef struct BhLimit
{
int pos1 ,pos2 ;
double min_value , max_value;
int min_pos , max_pos;
double avg;
double sum;
int len;
}BhLimit;
typedef vector<BhLimit> BhLimits;
int bhGetLimitSize(BhLimit limit)
{
return limit.pos2 - limit.pos1 + 1;
}
IplImage* bhGet8Depth(const IplImage* srcImage,int zeroFlag)
{
IplImage* resultImg;
if (srcImage->depth == 8)
{
resultImg= cvCreateImage(cvGetSize(srcImage),8,1);
if (zeroFlag == 1)
cvZero(resultImg);
else if (zeroFlag == 2)
{
if (srcImage->depth == 8 )
{
if ( srcImage->nChannels == 3)
cvCvtColor(srcImage,resultImg,CV_BGR2GRAY);
else if( srcImage->nChannels == 1)
cvCopyImage(srcImage,resultImg);
}
}
}
else if (srcImage->depth == IPL_DEPTH_32F)
{
if ( srcImage->nChannels ==1)
resultImg = cvCreateImage(cvGetSize(srcImage),8,1);
else if (srcImage->nChannels == 3)
resultImg = cvCreateImage(cvGetSize(srcImage),8,3);
cvNormalize(srcImage,resultImg,0,255,CV_MINMAX);
}
return resultImg;
}
void bhGetHorzProjection(IplImage* srcImage,CvMat* srcProj)
{
CvRect roi = cvGetImageROI(srcImage);
// CvMat* result = cvCreateMat(1,srcImage->height,CV_32FC1);
float* projP = srcProj->data.fl;
IplImage* rowImg = cvCreateImageHeader(cvSize(roi.width,1),8,1) ;
rowImg->imageData = srcImage->imageData + srcImage->widthStep * roi.y + roi.x;
rowImg->widthStep = srcImage->widthStep;
for (int i= roi.y; i < roi.y + roi.height ;i++)
{
projP[i - roi.y] = float(cvSum(rowImg).val[0]);
rowImg->imageData += rowImg->widthStep ;
}
cvReleaseImageHeader(&rowImg);
//return result;
}
CvMat* bhGetHorzProjection(IplImage* srcImage)
{
CvRect roi = cvGetImageROI(srcImage);
CvMat* result = cvCreateMat(1,roi.height,CV_32FC1);
bhGetHorzProjection(srcImage,result);
return result;
}
BhLimit bhGetLimitInfo(CvMat* proj ,int pos1,int pos2)
{
BhLimit result;
result.pos1 = pos1;
result.pos2 = pos2;
float* p = (float*) (proj->data.fl);
result.sum = p[pos1];
result.avg = p[pos1];
result.max_value = p[pos1];
result.min_value = p[pos1];
result.max_pos = 0;
result.min_pos = 0;
for (int j=pos1+1;j < pos2;j++)
{
result.sum += p[j];
if (p[j] > result.max_value)
{
result.max_value = p[j];
result.max_pos = j;
}
if (p[j] < result.min_value)
{
result.min_value = p[j];
result.min_pos = j;
}
}
result.len = result.pos2 - result.pos1 +1;
result.avg = result.sum / result.len;
return result;
}
void bhGetProjectionLimits(CvMat* proj,BhLimits& result)
{
//BhLimits result;
float* p = (float*) (proj->data.fl);
int j=0;
while ( j < proj->width)
{
if (p[j] > 0 )
{
int starttPos = j;
int endPos = j;
j++;
while ((j < proj->width) && (p[j] > 0))
{
j++;
endPos++;
}
BhLimit lim = bhGetLimitInfo(proj,starttPos,endPos);
result.push_back(lim);
}
j++;
}
//return result;
}
void bhQueryLimits(BhLimits& limits,unsigned char op,int minValue,int maxValue)
{
BhLimits result;
if (op == BH_LIMIT_POS1)
for (size_t i=0; i <limits.size();i++)
{
if (minValue <= limits[i].pos1 && limits[i].pos1 <= maxValue)
result.push_back(limits[i]);
}
else if (op == BH_LIMIT_POS2)
for (size_t i=0; i <limits.size();i++)
{
if (minValue <= limits[i].pos2 && limits[i].pos2 <= maxValue)
result.push_back(limits[i]);
}
else if (op == BH_LIMIT_SIZE)
for (size_t i=0; i <limits.size();i++)
{
int size = bhGetLimitSize(limits[i]);
if (minValue <= size && size <= maxValue)
result.push_back(limits[i]);
}
else if (op == BH_LIMIT_SUM)
for (size_t i=0; i <limits.size();i++)
{
if (minValue <= limits[i].sum && limits[i].sum <= maxValue)
result ...
(more)
What do you want to measure on your image?
I want to measure the width of the 3 bands formed , and then take their ratio . I have reached till the above image after various operations ( the original image had clear bands but edge detection wasnt possible , now it is due to clear difference between the bands and background)