Page 1 of 1
NewPixelRegionIterator
Posted: 2011-10-01T14:40:47-07:00
by rohitkrishna
Hi...
Iam a newbie to Image Magick. Iam tryin to use NewPixelRegionIterator in my program to grab a subregion from an image and has to print the pixel values of that region only.. My Code is ..
Code: Select all
void subimages_pxls(MagickWand *wand,size_t sbimg_wdt,size_t sbimg_hgt,int n)
{
size_t width=MagickGetImageWidth(wand);
size_t height=MagickGetImageHeight(wand);
int n_sbimg=(width*height)/(sbimg_wdt*sbimg_hgt); //sb Img width and height are taken from user input from main.
int i,j,k=0;
int row[n_sbimg],col[n_sbimg];
for(i=0;i<height;i=i+sbimg_hgt)
{
for(j=0;j<width;j=j+sbimg_wdt)
{
row[k]=i;
col[k]=j;
k++;
}
}
unsigned long x,y;
unsigned int red, green, blue;
n=n-1;
size_t r,c;
r=row[n];
c=col[n];
PixelIterator * rg_itr=NewPixelRegionIterator(wand,r,c,sbimg_wdt,sbimg_hgt);
PixelWand ** pixels;
for (y=row[n]; y<row[n]+sbimg_hgt; y++)
{
pixels = PixelGetNextIteratorRow(rg_itr, &sbimg_wdt);
for (x=col[n];x<col[n]+sbimg_wdt; x++)
{
red = (unsigned int) (255*PixelGetRed(pixels[x]));
green = (unsigned int) (255*PixelGetGreen(pixels[x]));
blue = (unsigned int) (255*PixelGetBlue(pixels[x]));
printf("At %ld,%ld, rgb : %d,%d,%d\n", x,y, red, green, blue);
}
printf("\n");
}
DestroyPixelIterator(rg_itr);
}
It is giving me segmentation fault when i run the program. Can Someone explain me and Solve the issue...It will be of great Help?
Thanks in advance.
Re: NewPixelRegionIterator
Posted: 2011-10-01T16:16:23-07:00
by el_supremo
n hasn't been declared or initialized. My guess is you meant:
Pete
Re: NewPixelRegionIterator
Posted: 2011-10-01T22:58:36-07:00
by rohitkrishna
el_supremo wrote:n hasn't been declared or initialized. My guess is you meant:
Pete
Sry My mistake.....i forgot to mention...
iam reading n from main function as user input....
Re: NewPixelRegionIterator
Posted: 2011-10-02T15:58:04-07:00
by el_supremo
Code: Select all
int n_sbimg=(width*height)/(sbimg_wdt*sbimg_hgt);
I don't think you're calculating the number of subimages properly.
It should be this:
Code: Select all
int n_sbimg=(width/sbimg_wdt)*(height/sbimg_hgt);
For example, if the original image is 640x480 and the subimages are 100x100, you can get 6 complete images along the width and 4 along the height for a total of 24 complete 100x100 sub-images.
But (640*480)/(100*100) is 30.
If you then call the function with a value of n greater than 23 it will fail one way or another.
Pete
Re: NewPixelRegionIterator
Posted: 2011-10-02T16:34:54-07:00
by rohitkrishna
el_supremo wrote:Code: Select all
int n_sbimg=(width*height)/(sbimg_wdt*sbimg_hgt);
I don't think you're calculating the number of subimages properly.
It should be this:
Code: Select all
int n_sbimg=(width/sbimg_wdt)*(height/sbimg_hgt);
For example, if the original image is 640x480 and the subimages are 100x100, you can get 6 complete images along the width and 4 along the height for a total of 24 complete 100x100 sub-images.
But (640*480)/(100*100) is 30.
If you then call the function with a value of n greater than 23 it will fail one way or another.
Pete
Thanks..for suggestion..for now iam just tryin to do for 15x15 image with 5x5 as sub image size. Am i using the newpixelregioniterator and PixelGetNextIteratorRow in the right way...?
Re: NewPixelRegionIterator
Posted: 2011-10-02T16:39:43-07:00
by rohitkrishna
The Problem with the program is it cannot access the pixel values from a point.....and i cannot figure it out why..?
Re: NewPixelRegionIterator
Posted: 2011-10-02T17:44:00-07:00
by anthony
I just spent the weekend looking at MagickWand source (research for IMv7 CLI redevelopment)
And while I have not coded in MagickWand (yet), I am familiar with it, and how IM programming works.
I believe you should be looping using a while() around PixelGetNextIteratorRow()
The row that is being processed can be retrieved with PixelGetIteratorRow(),
however what you are doing should work fine.
However the pixel in the row 'x' is handled as a value from 0 to region width, and not as a column number as you have.
That last would be the reason for the segmentation fault!
Finally you can't initialise new variables after your initial 'for' loops unless you start a new {...} block! That should be a compile time syntax error!
Re: NewPixelRegionIterator
Posted: 2011-10-03T08:19:25-07:00
by rohitkrishna
anthony wrote:I just spent the weekend looking at MagickWand source (research for IMv7 CLI redevelopment)
And while I have not coded in MagickWand (yet), I am familiar with it, and how IM programming works.
I believe you should be looping using a while() around PixelGetNextIteratorRow()
The row that is being processed can be retrieved with PixelGetIteratorRow(),
however what you are doing should work fine.
However the pixel in the row 'x' is handled as a value from 0 to region width, and not as a column number as you have.
That last would be the reason for the segmentation fault!
Finally you can't initialise new variables after your initial 'for' loops unless you start a new {...} block! That should be a compile time syntax error!
Code: Select all
for (y=row[n]; y<row[n]+sbimg_hgt; y++)
{
while(r<r+sbimg_hgt)
{
pixels = PixelGetNextIteratorRow(rg_itr, &sbimg_wdt);
r++;
}
for (x=col[n];x<col[n]+sbimg_wdt; x++)
{
red = (unsigned int) (255*PixelGetRed(pixels[x]));
green = (unsigned int) (255*PixelGetGreen(pixels[x]));
blue = (unsigned int) (255*PixelGetBlue(pixels[x]));
printf("At %ld,%ld, rgb : %d,%d,%d\n", x,y, red, green, blue);
}
printf("\n");
}
Is while Loop should Be lik this..?Or do i have to use PixelGetIteratorRow() also.
Re: NewPixelRegionIterator
Posted: 2011-10-03T08:55:10-07:00
by el_supremo
Your original for loops are closer to what you need but you are addressing the pixels array incorrectly.
When you call NewPixelRegionIterator it returns a linear array of sbimg_wdt pixels. You are addressing it as if it had returned a row from the whole image.
The for loop indices (especially of "x") need to be adjusted:
Code: Select all
for (y=0; y<sbimg_hgt; y++) {
pixels = PixelGetNextIteratorRow(rg_itr, &sbimg_wdt);
for (x=0;x<sbimg_wdt; x++) {
red = (unsigned int) (255*PixelGetRed(pixels[x]));
green = (unsigned int) (255*PixelGetGreen(pixels[x]));
blue = (unsigned int) (255*PixelGetBlue(pixels[x]));
printf("At %ld,%ld, rgb : %d,%d,%d\n", x,y, red, green, blue);
}
printf("\n");
}
Pete
Re: NewPixelRegionIterator
Posted: 2011-10-03T09:48:02-07:00
by rohitkrishna
el_supremo wrote:Your original for loops are closer to what you need but you are addressing the pixels array incorrectly.
When you call NewPixelRegionIterator it returns a linear array of sbimg_wdt pixels. You are addressing it as if it had returned a row from the whole image.
The for loop indices (especially of "x") need to be adjusted:
Code: Select all
for (y=0; y<sbimg_hgt; y++) {
pixels = PixelGetNextIteratorRow(rg_itr, &sbimg_wdt);
for (x=0;x<sbimg_wdt; x++) {
red = (unsigned int) (255*PixelGetRed(pixels[x]));
green = (unsigned int) (255*PixelGetGreen(pixels[x]));
blue = (unsigned int) (255*PixelGetBlue(pixels[x]));
printf("At %ld,%ld, rgb : %d,%d,%d\n", x,y, red, green, blue);
}
printf("\n");
}
Pete
Thankyou...for the solution..you have solved the problem. Big Thanks....
Re: NewPixelRegionIterator
Posted: 2011-10-03T18:34:10-07:00
by anthony
If you want to report the actual row and column of the pixel change the print to.
printf("At %ld,%ld, rgb : %d,%d,%d\n", c+x,r+y, red, green, blue);
If you want to write the prints back, modify the "pixels" array and then call PixelSyncIterator() appropriately.
just before the end of the 'y' loop.
However for any more complex work beyond straight pixel-by-pixel, that is convolutions or morphology type processing, I would probably go deeper and use MagickCore Pixel handling more directly.
Be warned however that MagickCore pixel handling has had major changes in IMv7 (mutli-channel), so stick with the more portable MagickWand if you can.