Ask Your Question
1

Width measurement of image parts

asked 2013-02-11 22:29:02 -0600

project_310 gravatar image

Hello

I've been working on opencv for past few days , I have successfully run tbe basic operations of images on it.

I have an image whose edge detection was performed and the edges are showing up now . Now , I need to measure the distance between the two edges Note : The edges are not straight lines , also the edges are basically part of a band .!

Also the edge detection of this image is not working , so I need help on both parts , the edge detection and also the width measurement of the 3 bands shown .

Any help would be appreciated .

image description

edit retag flag offensive close merge delete

Comments

What do you want to measure on your image?

Mathieu Barnachon gravatar imageMathieu Barnachon ( 2013-02-12 02:47:11 -0600 )edit

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)

project_310 gravatar imageproject_310 ( 2013-02-12 08:25:05 -0600 )edit

3 answers

Sort by » oldest newest most voted
2

answered 2013-02-12 12:32:46 -0600

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)
edit flag offensive delete link more

Comments

Thank you sir It's a good result , as I am pretty new to this , some explanation of your code would be very helpful..just a brief one will do ! And btw thanks a lot !

project_310 gravatar imageproject_310 ( 2013-02-13 05:11:12 -0600 )edit

It worked perfectly , thanks ! Now , I need to measure the width between the two red lines ( of all 3 red boxes ) I was thinking of traversing from one red pixel top to botton for all 3 , is that feasible in opencv? Can you suggest something else for measuring width ?

project_310 gravatar imageproject_310 ( 2013-02-14 02:53:19 -0600 )edit

BhLimit struct has len field when you call bhGetLimitInfo set it. For example limits[i].len

Mostafa Sataki gravatar imageMostafa Sataki ( 2013-02-14 03:05:39 -0600 )edit

I still am unable to find the width . Can you help me with the code for it pls ? It's urgent.

project_310 gravatar imageproject_310 ( 2013-02-28 06:18:10 -0600 )edit
0

answered 2013-02-12 08:34:24 -0600

To measure the width of the bands, you probably should used a connected component approach. You segment your bands into components, easily with the neighborhood search of black pixels. You keep only the biggest (with a threshold), and you can use statistical operations, like sum, average, ellipse fitting (in OpenCV), mean,... or use directly these components to find width and height (min in X and Y and max in X and Y). Additionally you may have to performed morphological math on your image (erode, dilate, Open/Close) to have better results.

edit flag offensive delete link more
0

answered 2014-02-11 07:59:31 -0600

ZHT gravatar image
edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2013-02-11 22:29:02 -0600

Seen: 1,757 times

Last updated: Feb 11 '14