Hi Jel:
I have to do some revamping in my guides, however that little nugget on addressing adjacent pixels is found in the intermediate image processing guide. I'll probably get around to it in the late fall / winter time. Summertime is for house repair and yard work.
https://skydrive.live.com/redir?resid=A ... ile%2c.pdf.
If you want nested loops that look in the 1d directions, look at the Gaussian Blur vertical and horizontal. If you want nested loops that look in the 2d direction, look at the Gaussian Blur 2d. The difference is in the separability of the filter. If you have a 2d nested loop, it is always slower than the 1d nested loop.
Here is an example of the 2d nested loops, which is used for Non-Linear filter
for(int y = 0; y < nHeight; y++)
{
for(int x = 0; x < nWidth; x++)
{
int ctrIdx = y * nWidth + x;
float redcenter; float greencenter; float bluecenter;
float redcenter = pBGRA_in[(ctrIdx) * 4 + CHANNEL_R];
float greencenter = pBGRA_in[(ctrIdx) * 4 + CHANNEL_G];
float bluecenter = pBGRA_in[(ctrIdx) * 4 + CHANNEL_B];
for(int j = max(0, y - size); j <= MIN(nHeight - 1, y + size); j++)
{
for(int i = max(0, x - size); i <= MIN(nWidth - 1, x + size); i++)
{
int idx = max(0, min(j, nHeight-1))*nWidth + max(0, min(i,nWidth-1));
float redKernelSlider = pBGRA_in[(idx) * 4 + CHANNEL_R];
float greenKernelSlider = pBGRA_in[(idx) * 4 + CHANNEL_G];
float blueKernelSlider = pBGRA_in[(idx) * 4 + CHANNEL_B];
//do your routine here
}//end I
}//end J
}//end x
}//end y
//////////////////////////////////////////////////////////////////////
The redcenter, greencenter and bluecenter are the center pixel of an odd sized kernel. While the redKernelSlider, greenKernelSlider and blueKernelSlider slide along the kernel to collect the pixel values in a 2d fashion.
The 1d example
for(int y = 0; y < nHeight; y++)
{
for(int x = 0;x < nWidth; x++)
{
for(int i = max(0, x - size); i <= MIN(nWidth - 1, x + size); i++)
{
float red = pBGRA_in[(i + y * nWidth) * 4 + CHANNEL_R];
float green = pBGRA_in[(i + y * nWidth) * 4 + CHANNEL_G];
float blue = factor * pBGRA_in[(i + y * nWidth) * 4 + CHANNEL_B];
//do your routine here
}//end I
}//end x
} //end y
for(int x = 0; x < nWidth; x++)
{
for(int y = 0; y < nHeight; y++)
{
for(int i = max(0, y - size); i <= MIN(nHeight – 1, y + size); i++)
{
red = pBGRA_in[(x + i * nWidth) * 4 + CHANNEL_R];
green = pBGRA_in[(x + i * nWidth) * 4 + CHANNEL_G];
blue = pBGRA_in[(x + i * nWidth) * 4 + CHANNEL_B];
}//end I
}//end y
}//end x
The difference here is separability in the kernels. If you can break your routine to use 2 passes rather than the 2d routine, it will always run faster.
JEL wrote:Hi Andy, I have a question I think you're the only one here who can answer
I've been over your SDK guide, but couldn't find what I was looking for. And I'm not good enough friends with CPP to be able to figure it out myself.
I have an image... a bayer-mosaic (a raw-file that hasn't been debayered/demosaiced).
This image is made up of 2x2 squares, with 1 red, 1 blue, and 2 green pixels. They are placed in the same order in each 2x2 square.
My goal is to have a script in the script node that can take the red and copy it to the 3 other pixels in its square, and take the blue and copy that to the 3 other pixels, and take the 2 greens and average them and then copy them to the 2 other pixels (or just take 1 green and treat the same way as done with the red and blue)
Am I making sense?
My problem is that I can't figure out how to read such 2x2 squares. I can figure out how to read single pixels, but not these... I guess they're called... bi-cubic squares.
I've attached a crop of one such bayer-mosaic.
The point of it all is to be able to attempt my own routines at demosaicing.
I imagine you already know how to look at adjacent pixels, since I guess that's needed for your denoise/blur plugins, so is this something you will include in your SDK guide?
Thanks