How can I do pixel-wise computation with a xf:Mat? - vivado-hls

I am trying to migrating my opencv code to Xilinx xfopencv. I want to do pixel wise division of two input images.c(x,y)=a(x,y)/b(x,y)
How can I get c by using xfOpenCv???
In OpenCv, I can directly do a/b, but xfOpenCv do not have pixel-wize division function. I tried to define a division function by myself.
but I got error: '[]' could not be resolved
So how can I do pixel-wise computation with a xf:Mat ?
Could you give an example?
error: '[]' could not be resolved
xf::Mat<XF_8UC1, HEIGHT, WIDTH, XF_NPPC1> a;
xf::Mat<XF_8UC1, HEIGHT, WIDTH, XF_NPPC1> b;
xf::Mat<XF_8UC1, HEIGHT, WIDTH, XF_NPPC1> c;
for (int i = 0; i < HEIGHT; i++)
for (int j = 0; j < WIDTH; j++)
{
c[i][j] = a[i][j]/b[i][j];
}

use the '.data' pointer to access each pixel value of an xf::Mat object.
for (int i = 0; i < HEIGHT; i++){
for (int j = 0; j < WIDTH; j++){
c.data[i*WIDTH+j] = a.data[i*WIDTH+j] / b.data[i*WIDTH+j];
}
}

Related

My blur filter doesn't seem to working correctly, even though if I test it using sample pictures they are blurred

Currently I am doing a computer course in which I have to write a blur filter for .BMG images.
The filter loads the pictures correctly, and creates new ones based on my filter.
I have tested the blur filter using sample pictures, and it seems to work (to my eye).
However the course has an auto grader in which I can see that my results differ.
Here is a link to my results, scroll all the way down to see the results for the blurr function:
https://submit.cs50.io/check50/73d0a0da48b323a1a8e306fc0ef528cd2df269c3
Here is the code that I wrote to solve this problem:
// Blur image
void blur(int height, int width, RGBTRIPLE image[height][width])
{
RGBTRIPLE TEMP[height][width];
for(int i = 0; i < height; i++)
{
for(int j = 0; j < width; j++)
{
TEMP[i][j].rgbtRed = image[i][j].rgbtRed;
TEMP[i][j].rgbtGreen = image[i][j].rgbtGreen;
TEMP[i][j].rgbtBlue = image[i][j].rgbtBlue;
}
}
// this forloop will read in the height
for(int i = 0; i < height; i++)
{
// this forloop will read in the with
for(int j = 0; j < width; j++)
{
float count = 0;
float red = 0;
float green = 0;
float blue= 0;
// this forloop will loop three times, for the average filter
for(int q = -1; q < 2; q++)
{
// this forloop will loop three times, making the total 9 for each pixel
for(int w = -1; w < 2; w++)
{
// this if statement makes sure that the I stay within the pixel I J array
if(w >= 0 && w < width && q >= 0 && q < height)
{
red += TEMP[i+q][j+w].rgbtRed;
green += TEMP[i+q][j+w].rgbtGreen;
blue += TEMP[i+q][j+w].rgbtBlue;
count ++;
}
else
{
continue;
}
}
}
// this should set the [i][j] value of each colour to the average of the values
image[i][j].rgbtRed = round(red/count);
image[i][j].rgbtGreen = round(green/count);
image[i][j].rgbtBlue = round(blue/count);
}
}
}
Hopefully someone can help me with my mistake.

pset4 blur Segmentation fault

I'm stuck on my code for too much time now and needing some help. I'm working on CS50 pset4 blur filter and I keep getting either a "Segmentation fault" or "Floating point exception" depending if try to change my " neighbour variables" on float instead of int. Can someone have any idea what I'm doing wrong with that ?
// Blur image
void blur(int height, int width, RGBTRIPLE image[height][width])
{
// Copy image to "copy"
RGBTRIPLE copy[height][width];
for(int i = 0; i < height; i++)
{
for(int j = 0; j < width; j++)
{
copy[i][j] = image[i][j];
}
}
// Loop through all the neighbour's pixel and calculate the average RGB in each
int RedNeighbour = 0; int BlueNeighbour = 0; int GreenNeighbour = 0; int neighbourSum = 0;
for(int i = 0; i < height; i++)
{
for(int j = 0; j < width; j++)
{
for(int k = i - 1; k < i + 1; k++)
{
for(int l = j - 1 ; l < j + 1; l++)
{
if(k >= 0 && k < height && l >= 0 && l < width)
{
RedNeighbour += copy[l][k].rgbtRed;
BlueNeighbour += copy[l][k].rgbtBlue;
GreenNeighbour += copy[l][k].rgbtGreen;
neighbourSum++;
}
else
{
continue;
}
}
}
// Divide each color by the sum of the neighbouring pixels and copy the pixe into original image
image[i][j].rgbtRed = round(fmin(255, RedNeighbour/neighbourSum));
image[i][j].rgbtBlue = round(fmin(255, BlueNeighbour/neighbourSum));
image[i][j].rgbtGreen = round(fmin(255, GreenNeighbour/neighbourSum));
}
}
return;
}
Thanks !
I'd recommend just using a debugger (gdb, or your IDE's if you're using one) for that kind of thing.
That said, I'm noticing that on the following lines, you are potentially accessing out of bound indices in your copy array:
RedNeighbour += copy[l][k].rgbtRed;
BlueNeighbour += copy[l][k].rgbtBlue;
GreenNeighbour += copy[l][k].rgbtGreen;
In your code, l is constrained by your width, while k is constrained by your height. However, the definition of the copy array is RGBTRIPLE copy[height][width];, which means that you should probably be accessing your copy array with copy[k][l] rather than copy[l][k].

Most efficient way to expand 2D array, with dimension (n x m) to a new array of dimension (n + w)(m + w), while keeping contents centered

I got an assigment for a set of programs that manipulate PPM image files. One of these programs consists of adding a colored frame of width w around the original image.
It wasn't very hard finding a solution, but I'm curious if it can be optimized as it doesn't seem the most elegant way to do it.
Im using an array pixel ** (inside a struct ppmfile which also contains header data) to store the image data, it is allocated with this function:
pixel **imgdata(int xsize, int ysize)
{
pixel **imgdata;
imgdata = (pixel**)malloc(ysize*sizeof(pixel*));
for(int i = 0; i < ysize; i++)
(imgdata)[i] = (pixel*)malloc(xsize*sizeof(pixel));
return imgdata;
}
This is the function I came up with:
void frame(ppmfile *ppm, int width, pixel color)
{
pixel **new_image = imgdata(ppm->xsize + (width*2), ppm->ysize + (width*2));
//Copying to center of new pixel matrix
for(int i = 0; i < ppm->ysize; i++)
for(int j = 0; j < ppm->xsize; j++)
new_image[width + i][width + j] = ppm->imgdata[i][j];
free_ppmimgdata(ppm);
ppm->imgdata = new_image;
ppm->xsize += width*2;
ppm->ysize += width*2;
//frame sides
for (int i = 0; i < width; i++)
for(int j = 0; j < ppm->xsize; j++)
{
ppm->imgdata[i][j] = color;
ppm->imgdata[ppm->ysize - i - 1][j] = color;
}
//frame top and bottom
for(int i = width; i < ppm->ysize - width; i++)
for (int j = 0; j < width; j++)
{
ppm->imgdata[i][j] = color;
ppm->imgdata[i][ppm->xsize - j - 1] = color;
}
}
But this allocates an entirely new, bigger, array in memory while also having imo too many loops for something this simple... So my question is if it's possible to realloc() this type of matrix, while moving/copying/preserving its contents at the "center" of the new matrix - as (poorly) illustrated here? Are there any other ways you can see to optimize this?
Thanks in advance!

Reflecting (flipping) an image horizontally in C using 'temp' array

I am trying to reflect(filp horizontally) an image and I can't quite seem figure out why the image does not reflect and stays in original condition. I've tried many different methods (adding -1 to [width - j] or assigning the tempArray as RGBTRIPLE tempArray;and dividing width with /2 as the loop condition.
No errors being thrown, and I've followed the solutions from Stackoverflow and it seems like I am not quite getting there, any advices?
// Reflect image horizontally
void reflect(int height, int width, RGBTRIPLE image[height][width])
{
RGBTRIPLE tempArray[height][width];
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
tempArray[i][j] = image[i][j];
image[i][j] = image[i][width - j];
image[i][width - j] = tempArray[i][j];
}
}
return;
}
As mentioned in the comments, you have 2 issues. First, since you iterate over the entire row, you end up swapping each item 2x. And that leaves just the original array.
Second, you access one past the end of the array with image[i][width - j] when j == 0. Valid indexes for an array are 0...(length-1).
Another, minor issue is that you don't need an array for the temp value.
// Reflect image horizontally
void reflect(int height, int width, int image[height][width])
{
int temp;
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width / 2; j++)
{
temp = image[i][j];
image[i][j] = image[i][width - j - 1];
image[i][width - j - 1] = temp;
}
}
return;
}
Tested: https://ideone.com/EAALtI

How I can resize a bitmap properly?

I want to downsample the bitmap of a BMP file by a factor M. I want to obatain the image without aliasing. So in order to achieve it I compute the mean of the MxM pixels in this way:
The problem apears when I try to resize non-squared images because it only compute the mean proprely in a square. For example, if the final image is 300x150, the mean is right until 150x150 pixel. If I had the previous_mean -> new_mean = (previous_mean+value)/2
This is how I actually compute it:
for (i = 0; i < new_height; i++) {
for (j = 0; j < new_width; j++) {
mean.r = bitmap[i*factor][j*factor].r;
mean.g = bitmap[i*factor][j*factor].g;
mean.b = bitmap[i*factor][j*factor].b;
for(k = i*factor; (k < i*factor+factor)&&(k<old_height); k++){
for(l = j*factor; (l < j*factor+factor)&&(l<old_width); l++){
mean.r = (mean.r + bitmap[k][l].r)/2;
mean.g = (mean.g + bitmap[k][l].g)/2;
mean.b = (mean.b + bitmap[k][l].b)/2;
}
}
new_bitmap[i][j] = mean;
mean.r = 0;
mean.g = 0;
mean.b = 0;
}
}
new_bitmap and bitmap are 2-D array of PIXELS, being PIXELS:
typedef struct __attribute__((__packed__)){
unsigned char b;
unsigned char g;
unsigned char r;
} PIXELS;
This is absolutely correct, I were permutating the old_width with the old_heigth.

Resources