Straightening Out A Circle?

  • Thread starter Thread starter Craig Parsons
  • Start date Start date
C

Craig Parsons

Folks,

I have a scanned image which is circular, and contains a trace in the
middle of it (for those of you familar with trucks it is a tachograph
chart!).

I want to "flatten" it out, into a straight line. I can't seem to find
any controls which might be able to do this for me.

Does anyone have any ideas, or will I have to write some code to do it
pixel by pixel??

Thanks In Advance.


Craig.
 
Craig said:
Folks,

I have a scanned image which is circular, and contains a trace in
the middle of it (for those of you familar with trucks it is a
tachograph chart!).

I want to "flatten" it out, into a straight line. I can't seem to
find any controls which might be able to do this for me.

Does anyone have any ideas, or will I have to write some code to
do it pixel by pixel??

Thanks In Advance.


Craig.

I don't think there are standard classes for this, you have to write your own.

It would be something like:
- find the position / size / center of the circle
- find the start angle of the trace
- follow the trace in angle/radius coordinates
(possibly: step through the angle-range with some resolution, for a given angle
find the radius where the traceline is)
- plot in new x/y graph, x=recorded angle, y=recorded radius

Nice project. Sorry, I can't help you further with the "how" of these steps.

Hans Kesting
 
Well, does this have to be a dynamic process? are you only trying to
flatten this data once for display, or will this be an ongoing process?
If only once, then consider just doing it manually (ie. by hand) as
the time it would take to write this tool would probably outweigh the
time to do it by hand.

If however you really need for this to be done dynamically, then Han's
suggestion is in fact what you need to do. Here's a kick ass article
that should show you everything you need to do to access the nitty
gritty pixel data:

http://www.codeproject.com/cs/media/csharpgraphicfilters11.asp

Hope that helps,
Joel Martinez
http://www.onetug.org - Orlando .NET User Group
http://www.codecube.net - blog
 
Thanks,

It does need to be dynamic as I will want to do it on a scanned image a
lot of times for different images, so thanks very much for the link.


Craig.
 
I think the best way for this might be to produced a clever transformation
matrix to warp the picture straight using GDI+ in the System.Drawing
namespace. I wouldn't know where to start personally but try reading a bit
about it at www.bobpowell.net/faqmain.htm

Sorry I cant be more help

Ciaran
 
Craig Parsons said:
I have a scanned image which is circular, and contains a trace in the
middle of it (for those of you familar with trucks it is a tachograph
chart!).

I want to "flatten" it out, into a straight line. I can't seem to find
any controls which might be able to do this for me.

Does anyone have any ideas, or will I have to write some code to do it
pixel by pixel??

Yup, pixel by pixel. I couldn't help myself and quickly wrote it.
If I feed this a bitmap with a circle at the center, it returns a bitmap
with
a straight line so I guess it works. (No guarantees though !) :

public static Bitmap UnCircularWarp(Bitmap cb) 'cb stands for circular
bitmap
{
int width = Math.Min(cb.Width, cb.Height);
Bitmap bTemp = new Bitmap((width << 1) + 1, (width >> 1) + 1,
cb.PixelFormat);
double r = width / 2.0f;
for (int x = 0; x < bTemp.Width; ++x)
{

// as X goes from 0 to bTemp.width, alpha goes from PI to -PI
double alpha = Math.PI - Math.PI * 2.0d * (double)x / (double)bTemp.Width;

double cosA = Math.Cos(alpha);
double sinA = Math.Sin(alpha);
for (int y = bTemp.Height - 1; y >= 0; y--)
{
bTemp.SetPixel(
x,
y,
cb.GetPixel(
(int)(Math.Floor(r + (double)y * cosA)), ' circular transform to
determine pos. in circular bitmap
(int)(Math.Floor(r - (double)y * sinA)) ' circular transform to
determine pos. in circular bitmap
)
);
}
}
return bTemp;
}

Basically this creates a bitmap, half the height of the original bitmap (and
twice the width to make
sure that we have enough pixels to show the result.) Then it walks across
the destination (i.e.
unwarped bitmap) and calculates which position this corresponds to in the
cirular (i.e. original)
bitmap. The formula for the inverse image coordinate transform is simply a
circular mapping (i.e.
x = centerX + radius*cos(alhpa)
y = centerY + radius*sin(alpha)
adapted for screen coordinates (where 0,0 lies at the top left instead of
the bottom left)

Keep in mind that this is *hugely* inefficient. SetPixel is not really a
great way to do image warping.
Ideally you'd want to write this in C(++) for speed.

Have fun.

L2
 
Back
Top