NewPixelRegionIterator

Questions and postings pertaining to the usage of ImageMagick regardless of the interface. This includes the command-line utilities, as well as the C and C++ APIs. Usage questions are like "How do I use ImageMagick to create drop shadows?".
Post Reply
rohitkrishna
Posts: 43
Joined: 2011-10-01T14:34:04-07:00
Authentication code: 8675308

NewPixelRegionIterator

Post 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.
Last edited by rohitkrishna on 2011-10-01T23:00:31-07:00, edited 1 time in total.
el_supremo
Posts: 1015
Joined: 2005-03-21T21:16:57-07:00

Re: NewPixelRegionIterator

Post by el_supremo »

Code: Select all

n=n-1;
n hasn't been declared or initialized. My guess is you meant:

Code: Select all

n=k-1;
Pete
Sorry, my ISP shutdown all personal webspace so my MagickWand Examples in C is offline.
See my message in this topic for a link to a zip of all the files.
rohitkrishna
Posts: 43
Joined: 2011-10-01T14:34:04-07:00
Authentication code: 8675308

Re: NewPixelRegionIterator

Post by rohitkrishna »

el_supremo wrote:

Code: Select all

n=n-1;
n hasn't been declared or initialized. My guess is you meant:

Code: Select all

n=k-1;
Pete
Sry My mistake.....i forgot to mention...
iam reading n from main function as user input....
el_supremo
Posts: 1015
Joined: 2005-03-21T21:16:57-07:00

Re: NewPixelRegionIterator

Post 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
Sorry, my ISP shutdown all personal webspace so my MagickWand Examples in C is offline.
See my message in this topic for a link to a zip of all the files.
rohitkrishna
Posts: 43
Joined: 2011-10-01T14:34:04-07:00
Authentication code: 8675308

Re: NewPixelRegionIterator

Post 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...?
rohitkrishna
Posts: 43
Joined: 2011-10-01T14:34:04-07:00
Authentication code: 8675308

Re: NewPixelRegionIterator

Post by rohitkrishna »

The Problem with the program is it cannot access the pixel values from a point.....and i cannot figure it out why..?
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: NewPixelRegionIterator

Post 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!
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
rohitkrishna
Posts: 43
Joined: 2011-10-01T14:34:04-07:00
Authentication code: 8675308

Re: NewPixelRegionIterator

Post 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.
el_supremo
Posts: 1015
Joined: 2005-03-21T21:16:57-07:00

Re: NewPixelRegionIterator

Post 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
Sorry, my ISP shutdown all personal webspace so my MagickWand Examples in C is offline.
See my message in this topic for a link to a zip of all the files.
rohitkrishna
Posts: 43
Joined: 2011-10-01T14:34:04-07:00
Authentication code: 8675308

Re: NewPixelRegionIterator

Post 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.... :D
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: NewPixelRegionIterator

Post 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.
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
Post Reply