How do I create a Drawing.Region and add pixels to it?

T

trant

because of the way I scan an image I need to be able to create Region objects
and add pixel by pixel to different regions.

Any idea how to do this?

Pseudo code:

Region region1 = new Region();
Region region2 = new Region();

// scan through an image with x,y coords and sampling pixel at each coord

if (GetPixel(x,y) == Region1Test)
region1.AddPixel(x,y);
else
region2.AddPixel(x,y);


Again, just pseudo code - just meant to convey the functionality I am
looking for - mainly being able to expand a region pixel by pixel...
 
P

Peter Duniho

trant said:
[...]
if (GetPixel(x,y) == Region1Test)
region1.AddPixel(x,y);
else
region2.AddPixel(x,y);


Again, just pseudo code - just meant to convey the functionality I am
looking for - mainly being able to expand a region pixel by pixel...

You have to add single-pixel rectangles to the Region.

Note that this is going to be slow, along with the call to GetPixel()
itself. You're not specific about _why_ you want to do this, but I
would guess that whatever your ultimate goal, there is a better, more
efficient approach you could be using.

As long as you're dealing with very small images, the above should be
fine though.

Pete
 
J

Jeff Johnson

because of the way I scan an image I need to be able to create Region
objects
and add pixel by pixel to different regions.

Any idea how to do this?

Pseudo code:

Region region1 = new Region();
Region region2 = new Region();

// scan through an image with x,y coords and sampling pixel at each coord

if (GetPixel(x,y) == Region1Test)
region1.AddPixel(x,y);
else
region2.AddPixel(x,y);


Again, just pseudo code - just meant to convey the functionality I am
looking for - mainly being able to expand a region pixel by pixel...

I just want to point out that regions aren't images and therefore do not
contain pixels. You should really be thinking in terms of adding POINTS to
the region, or even more specifically, 1 x 1 rectangles. For that you might
consider the Union() method.

But I agree with Pete: we can probably help you better if we knew what it
was you were trying to accomplish. Regions have limited usefulness. Mostly
they're good for hit-testing and clipping. Are either of those what you plan
on using your region for?
 
T

trant

Hi Peter!

I realize it wont be efficient but I do not have the ability to do the
efficient way.

You may recall that a few months ago I posted here questions about tracing
borders of a homogeneous color filled image map which I wanted to read into
separate regions. The right way would be an algorithm that traced borders
around these colored regions into a GraphicsPath and used that to instantiate
my regions.

However that approach is too difficult for me. I am unable to find some
example out there that would give me a good foundation to work off and I lack
the understanding to do it myself. There are many abstract articles on this
but again, I just can't seem to grasp the concept wlel enough to apply it to
my situation.

So I am reverting to this terrible method of just scanning line by line and
adding pixel by pixel to a "region".

I will see how it goes with 1 pixel rectangles, thanks!

Peter Duniho said:
trant said:
[...]
if (GetPixel(x,y) == Region1Test)
region1.AddPixel(x,y);
else
region2.AddPixel(x,y);


Again, just pseudo code - just meant to convey the functionality I am
looking for - mainly being able to expand a region pixel by pixel...

You have to add single-pixel rectangles to the Region.

Note that this is going to be slow, along with the call to GetPixel()
itself. You're not specific about _why_ you want to do this, but I
would guess that whatever your ultimate goal, there is a better, more
efficient approach you could be using.

As long as you're dealing with very small images, the above should be
fine though.

Pete
.
 
T

trant

Jeff Johnson said:
But I agree with Pete: we can probably help you better if we knew what it
was you were trying to accomplish. Regions have limited usefulness. Mostly
they're good for hit-testing and clipping. Are either of those what you plan
on using your region for?

Hi Jeff,

Yeah I need them for hit testing and filling (coloring).

Basically, I read a map image which is filled with several uniquely colored
homogeneous regions. Think maybe a map of a state where all it's counties are
colored with unique solid colors.

I would scan this index map to establish a region for each unique county -
adding pixel (or points) to a Region object or what-not which would represent
each individual county.

Then I draw a map to screen for the user, perhaps a nice geological map of
the same state in the same dimensions. And as the user hovers their mouse
over this map I know exactly what county they are hovering because of a hit
test against those regions I gathered from the index map.

Then perhaps the user wants to click a button to paint all counties with
population density > 2500 persons per square mile, so I could easily filter
my collection of regions to just the ones which meet that criteria and can
easily overlay those counties on the map with some color and an opacity.

That is my goal.

Again, the right approach would be to write an algorithm that can actually
trace the borders of those counties from the input index map, but I just
can't figure that out.
 
P

Peter Duniho

trant said:
[...]
Basically, I read a map image which is filled with several uniquely colored
homogeneous regions. Think maybe a map of a state where all it's counties are
colored with unique solid colors.

[...]
Again, the right approach would be to write an algorithm that can actually
trace the borders of those counties from the input index map, but I just
can't figure that out.

My first thought: assuming you're of average intelligence or better (and
if you've figured out how to program and post to this newsgroup, surely
you are), it is implausible to me that you simply can't figure out any
of the algorithms suggested previously.

I haven't double-checked, but my recollection is that in at least one
case, the entire implementation was even provided in some form
(pseudo-code or some actual programming language). But even without
such explicit guidance, with some effort you should be able to figure
things out.

My second thought: when you describe the problem as a "map", are you
literally talking about an actual geo-political map of cities, states,
countries, etc? If so, then it is practically guaranteed that you could
in fact just obtain the data already in a practical format for dealing
the areas as regions (i.e. a polygon). Having to convert from a
color-coded map to a polygon or other format yourself seems like a lot
of extra, unnecessary work.

All that said, if you do insist on using the Region class, examining
each pixel individually, a couple of suggestions:

– Unless you know that each region on the map is a completely unique
color (many maps reuse colors, simply ensuring that adjacent regions
aren't the same color), you still have a problem identifying individual
regions, rather than getting some Region instance that contains two
discontiguous areas.

– If you do know that each region on the map has a unique color, then
IMHO it would be better to enumerate every pixel by row and column,
using a Dictionary<Color, Region> to quickly map from color to a
specific region instance you're building for that color.

– In any case, you definitely should learn about the
Bitmap.LockBits() or BitmapSource.CopyPixels() methods, either of which
you can use to obtain a raw data form of the image data, which will be
MUCH faster to examine than using GetPixel(). GetPixel() is easier to
use, but it's so much slower that the investment in learning how to
examine the pixel data directly when it's in an array is worthwhile.

Pete
 
T

trant

Hi Pete, Thanks for the reply!

Peter Duniho said:
My first thought: assuming you're of average intelligence or better (and
if you've figured out how to program and post to this newsgroup, surely
you are), it is implausible to me that you simply can't figure out any
of the algorithms suggested previously.

I haven't double-checked, but my recollection is that in at least one
case, the entire implementation was even provided in some form
(pseudo-code or some actual programming language). But even without
such explicit guidance, with some effort you should be able to figure
things out.

Sadly I regret to admit I was unable to implement any of those ideas to my
problem. As far as I recall they were very specific to edge detection
algorithms in photographs and the complexity has made it difficult to
understand it in more simple terms.
My second thought: when you describe the problem as a "map", are you
literally talking about an actual geo-political map of cities, states,
countries, etc? If so, then it is practically guaranteed that you could
in fact just obtain the data already in a practical format for dealing
the areas as regions (i.e. a polygon). Having to convert from a
color-coded map to a polygon or other format yourself seems like a lot
of extra, unnecessary work.

I use the county map example only to easily describe my scenario. But I
dont use any actual geopolitical maps - definitely nothing which would have
any shapefile data available.
All that said, if you do insist on using the Region class, examining
each pixel individually, a couple of suggestions:

– Unless you know that each region on the map is a completely unique
color (many maps reuse colors, simply ensuring that adjacent regions
aren't the same color), you still have a problem identifying individual
regions, rather than getting some Region instance that contains two
discontiguous areas.

Well, each region does have its own unique color, however there are cases of
a region being discontinuous - a few regions are actually made up of several
separate pieces. Would that cause a problem with Region?
– If you do know that each region on the map has a unique color, then
IMHO it would be better to enumerate every pixel by row and column,
using a Dictionary<Color, Region> to quickly map from color to a
specific region instance you're building for that color.

I am not sure I understand this. The only reason I would be scanning the
index map file is to build my list of regions which describe the areas of the
image which belong to them.

Then when I need to do a hit test on mouse position - I iterate through
these regions and do I guess a Contains operation on the mouse point for each
one until I find the one I am on.

Or if I need to color in regions I can just iterate through the list of
regions and then do a FillRegion on the ones which require coloring.

I am not sure what case I would need to retrieve a region from a color once
I have already built my list of regions
– In any case, you definitely should learn about the
Bitmap.LockBits() or BitmapSource.CopyPixels() methods, either of which
you can use to obtain a raw data form of the image data, which will be
MUCH faster to examine than using GetPixel(). GetPixel() is easier to
use, but it's so much slower that the investment in learning how to
examine the pixel data directly when it's in an array is worthwhile.

Yeah I do use this - in fact it was you who recommended using this approach
for iterating through the pixels in the index map. When all was said and done
it cut my processing time from something like 2+ minutes to several seconds.
So thank you for that invaluable suggestion!
 
P

Peter Duniho

trant said:
Sadly I regret to admit I was unable to implement any of those ideas to my
problem. As far as I recall they were very specific to edge detection
algorithms in photographs and the complexity has made it difficult to
understand it in more simple terms.

Okay. Well, just keep those in mind, and understand that if you think
you're unable to understand them, you just need more confidence in
yourself. It is not actually the case that they are incomprehensible. :)
[...]
– Unless you know that each region on the map is a completely unique
color (many maps reuse colors, simply ensuring that adjacent regions
aren't the same color), you still have a problem identifying individual
regions, rather than getting some Region instance that contains two
discontiguous areas.

Well, each region does have its own unique color, however there are cases of
a region being discontinuous - a few regions are actually made up of several
separate pieces. Would that cause a problem with Region?

Regions can be discontiguous. So assuming that's a valid condition for
your data, no problem at all.

(In fact, even in the case of actual geopolitical mapping, you
occasionally run into discontiguous regions…the issue I'm talking about
is specifically that where you might detect a discontiguous region when
you _don't_ want to. But I gather that's not an issue for you).
I am not sure I understand this. The only reason I would be scanning the
index map file is to build my list of regions which describe the areas of the
image which belong to them.

Sure. But, how many different regions are there? How do you know, for
a given pixel, which region you want to add that pixel to?

If the number of regions is small and pre-determined, I suppose you can
hard-code them into your code (e.g. a switch statement). But otherwise,
it seems to me it would be useful for any given pixel color to
immediately get the Region instance to which you want to add that
single-pixel area. A Dictionary<Color, Region> is a natural, efficient
way to do that.

Of course, once the Region instances are completely constructed, you
likely would not need the dictionary itself; just the list of Region
instances contained within.
Then when I need to do a hit test on mouse position - I iterate through
these regions and do I guess a Contains operation on the mouse point for each
one until I find the one I am on.

Note that for hit-testing, you don't need regions. Assuming you know
what color goes to what mapped area, just keep the original bitmap
around and check the color in the bitmap for the mouse position being
checked.
Or if I need to color in regions I can just iterate through the list of
regions and then do a FillRegion on the ones which require coloring.

Depending on how much memory you're willing to use, you can also solve
this without Regions. Instead, just create a mask bitmap (same size as
the original bitmap) for each area you want, where the mask is set where
the color corresponding to that area is present in the original. Then
through color mapping (see the ColorMatrix class) and compositing, you
can redraw the given area in any arbitrary color you want.

It's possible that Region will address your needs, but if not and if you
still do not want to continue your investigation into the other
techniques, these alternatives might be useful.

Pete
 
F

Family Tree Mike

Hi Pete, Thanks for the reply!

:


I use the county map example only to easily describe my scenario. But I
dont use any actual geopolitical maps - definitely nothing which would have
any shapefile data available.

Interesting that you used the term "shapefile". Even if no vector data
exists in shapefile format, which is a publicly open format for spatial
data by ESRI, you should be able to get any data found into that format.
ESRI even has a tool to take a scan and generate the vector data from
it. You could also digitize the data within the products.

I know there is a high cost associated with ESRI's software, but
frankly, it's worth it for real GIS analysis. It may even be worth
using the evaluation licensing to get the data to a format you want for
bundling with an app you are creating.
 
T

trant

Family Tree Mike said:
Interesting that you used the term "shapefile". Even if no vector data
exists in shapefile format, which is a publicly open format for spatial
data by ESRI, you should be able to get any data found into that format.
ESRI even has a tool to take a scan and generate the vector data from
it. You could also digitize the data within the products.

I know there is a high cost associated with ESRI's software, but
frankly, it's worth it for real GIS analysis. It may even be worth
using the evaluation licensing to get the data to a format you want for
bundling with an app you are creating.

Yeah it was the first thing that came to my mind trying to think of examples
of publicly available geographic map data. I worked on a project which
involved coloring the united states b zip codes using shapefile data but I
never actually worked on any algorithm to create the shapefiles- we just used
a tool that you fed zip codes to and it produced the shapefiles for us.

But this data I am dealing with now has no such possibility unless their
tool can generate the shapes from scanning an input image using an algorithm
which I have tried unsuccessfully to adapt myself.
 
T

trant

Peter Duniho said:
Hmmm...I replied to the previous message, but I haven't seen my post on
my own news server. I'm not sure at what point it got lost, but Google
managed to get a copy. So, rather than reposting the entire thing
again, here's a link:

http://groups.google.com/group/microsoft.public.dotnet.languages.csharp/msg/79736a859c68ae5f
.

Got it -

Okay now I understand the purpose of that color-to-region dictionary and it
makes perfect sense. Yeah I would definitely want to do that while scanning
and building the regions.

For hit testing alternative- that would mean keeping the index bitmap in
memory to reference it by sampling a color at a given x,y coord and see what
it maps to right? But the problem as you mentioned is if the image file is
too large and in my case the index map files and the "nice user interface
map" image are both large files > 50 megs. Ideally I'd keep only the one
image for display in memory.

And then I suppose the same issue would pose a problem with the color mask
layer since the image is very large. But that's a good idea

Thanks for your suggestions, Pete. I really appreciate your advice!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top