OpenCV - Curvilinear mapping with Hough transforms

Trust me I know it doesn't sound like a beginner topic, but I assure you I am a beginner.

I am playing with a hough transform. I have been able to tweak the data so that
only the circle I am interested in is found, and stored in CvSeq*

Is there a way to open up this circle, turning it in to a straight line, and map the image to follow this transformation. A nudge in the right direction is all I'm looking for.
No, you're right. It really doesn't.. but that's probably just because the topic is something I've never heard of. It got me to read your topic though :)

How is the circle defined in memory?

You'll need a way to read the circle information from memory (your CVSeq*) and translate it into whatever shape you want using whatever method you choose to do such.

I'm guessing you want a rectangle of width = circumference and height = radius from the circle image data.

Why don't you give us a little more information if this isn't enough of a nudge, which I don't suppose it is.
Sorry. about that. I guess it got you to pay attention :)
I was actually just about to delete my post because I was getting a headache, just trying to understand what I wrote :)

I have a large ring shaped image. The ring is composed of many smaller particles. I am trying to find a way to figuratively break open the circle and straighten the image to a very long rectangle.

While the Image bounds obviously have to be square I would like to preserve the deformation which would occur in this process.
In other words the particles at the top of the rectangle should be smaller on the x axis than the bottom particles, roughly proportional to R with a factor of 2*PI.
R being the original radius.

I recently discovered this Hough circle transform "cvHoughCircles()" which is able to digest this image matrix, find a circle to represent the curve stored in a type which OpenCV calls a sequence CvSeq* It looks like the actual output however is actually stored in a type called CvMemStorage.

1
2
3
4
5
6
7
8
9
10
typedef struct CvMemStorage
{
    int signature;
    CvMemBlock* bottom;           /* First allocated block.                   */
    CvMemBlock* top;              /* Current memory block - top of the stack. */
    struct  CvMemStorage* parent; /* We get new blocks from parent as needed. */
    int block_size;               /* Block size.                              */
    int free_space;               /* Remaining free space in current block.   */
}
CvMemStorage;


What I'm trying to do (at least I think this makes sense) is fit it to a straight line, and map the image to this.
Maybe it wouldn't even be curvilinear. I guess you could use a transformation matrix to map a circle to a straight line right? Maybe not. I actually did pretty bad in linear algebra.

If you can think of a better solution, or have the slightest idea how I might go about this, I would appreciate any input.
I'm confused about the structure the circle is being stored in. I've looked up the definitions of CVMemStorage and CVMemBlock, and both appear to have no room for data.

Here is CVMemBlock and you've already posted CVMemStorage:
1
2
3
4
5
typedef struct CvMemBlock
{
    struct CvMemBlock* prev;
    struct CvMemBlock* next;
} CvMemBlock;


It's a doubly linked list, but there's no pointer to the data of each node.. Just a pointer to the previous and next node.. where's the data supposed to go?

Usually images are arrays of pixel information. For instance bytes are typically used to represent colors.

Usually 4 bytes ( a long integer, or int) is used to describe a single pixel.

RGBA is a typical format, where R represents Red color, G represents green, B represents blue, and A represents alpha.

An entire picture is then composed out of an array of these pixels.

int picture [WIDTH][HEIGHT];

where picture[0]0] would be the first pixel on the top left and
picture[WIDTH-1][HEIGHT-1] would be the last pixel on the bottom right.

Is there a way to get the image data in a array like this?
A 1D array would be fine, but we need the pixel information in order to work on any sort of transformation.
I think I have it figured out. Or at least partially. I apologize my skills are lacking and I didn't unserstand this furnction very well before borrowing code.

here is my function which right now doesn't do anything but produces the circle and overlays it on the source image.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
void houghcircle(IplImage * src)
{
  char* windowname="Hough Circle Detection";
  CvMemStorage* storage = cvCreateMemStorage(0);
  cvSmooth(src,src, CV_GAUSSIAN,5,5);
  CvSeq* results = cvHoughCircles(
                                src,
                                storage,
                                CV_HOUGH_GRADIENT,
                                4,                       ///Denominator for resize fraction, making this number larger greatly speeds up calculation
                                src->width/3             ///Minimum circle size to find src->width/3 seems to work for now
                                );

    cout << results->total << " blocks of size " << results->elem_size <<" bytes.\n";
    cout <<"# Offset     X    Y    ?\n";
    for (int i =0; i< results->total; i++)
    {
        float* p = (float*) cvGetSeqElem( results,i);
        cout << i << " " << p << " " << p[0] << " " << p[1] << " " << p[2] << " " << p[3]<< " " << p[4]<< " " << p[5]<< " " << p[6]<< endl;
        CvPoint pt = cvPoint(cvRound(p[0]),cvRound(p[1]));
        cvCircle(
                src,                       ///source
                pt,                        ///center
                cvRound(p[2]),             ///Radius
                CV_RGB(0xff,0xff,0xff),    ///Color
                10                         ///Thickness
                 );
    }

  cvNamedWindow( windowname,1);
  cvShowImage(windowname,src);
  cvWaitKey();
  cvDestroyWindow(windowname);
}


It appears that the key is the CvSeq after all which appears to be a structure which keeps track of a series of signed character pointers.
The loop in the function uses that cvGetSeqElem() to extract entries in which the first two values of the array point to the x,y coordinates of a circle and the third is the radius. Anything after that just goes on to the next circle.

While this is very interesting and a very powerful function I'm already starting to have my doubts about using this function for what I need to do. Since I made the ring I know that at least one circle I already have this Information. I don't suppose you have any other Ideas?
What do you mean by:
Is there a way to open up this circle, turning it in to a straight line, and map the image to follow this transformation. A nudge in the right direction is all I'm looking for.


If you know a point on the edge and the center point then you can figure out the circumference. The circumference would be the length of your straight line, starting... where?... Plot the length of your line vs the angle you want the line to go and find your end point.

But what is "map the image"?
Topic archived. No new replies allowed.