Convert one-dimensional RGB byte array into c++ bitmap - c++

This question has been asked before on this site, but my problem is a little different and I cannot piece together other people's code to fit my goal. To make things better, the Windows documentation for LockBits(), CreateBitmap(), and many other possible relevant functions has no examples and barely even specifies what the parameters are.
What I'm trying to do is to create an image out of an array of bytes that represent the colors of the image. The array is three times as large as the number of pixels on the screen so that there is a red, green, and blue element for each pixel. Each pixel's color can be described as RGB(x + (width * y), x + (width * y) + 1, x + (width * y) + 2), where x and y are the coordinates of the point and width is the width of the image.
The last thing is that I would like to do it in C++ with standard libraries.
If it's not too much trouble, could anyone help me in this puzzle?

Related

How can I draw smooth pixels in a netpbm image?

I just wrote a small netpbm parser and I am having fun with it, drawing mostly parametric equations. They look OK for a first time thing, but how can I expand upon this and have something that looks legit? This picture is how my method recreated the Arctic Monkeys logo which was just
0.5[cos(19t) - cos(21t)]
(I was trying to plot both cosines first before superpositioning them)
It obviously looks very "crispy" and sharp. I used as small of a step size as I could without it taking forever to finish. (0.0005, takes < 5 sec)
The only idea I had was that when drawing a white pixel, I should also draw its immediate neighbors with some slightly lighter gray. And then draw the neighbors of THOSE pixels with even lighter gray. Almost like the white color is "dissolving" or "dissipating".
I didn't try to implement this because it felt like a really bad way to do it and I am not even sure it'd produce anything near the desirable effect so I thought I'd ask first.
EDIT: here's a sample code that draws just a small spiral
the draw loop:
for (int t = 0; t < 6 * M_PI; t += 0.0005)
{
double r = t;
new_x = 10 * r * cosf(0.1 * M_PI * t);
new_y = -10 * r * sinf(0.1 * M_PI * t);
img.SetPixel(new_x + img.img_width / 2, new_y + img.img_height / 2, 255);
}
//img is a PPM image with magic number P5 (binary grayscale)
SetPixel:
void PPMimage::SetPixel(const uint16_t x, const uint16_t y, const uint16_t pixelVal)
{
assert(pixelVal >= 0 && pixelVal <= max_greys && "pixelVal larger than image's maximum max_grey\n%d");
assert(x >= 0 && x < img_width && "X value larger than image width\n");
assert(y >= 0 && y < img_height && "Y value larger than image height\n");
img_raster[y * img_width + x] = pixelVal;
}
This is what this code produces
A very basic form of antialiasing for a scatter plot (made of points rather than lines) can be achieved by applying something like stochastic rounding: consider the brush to be a pixel-sized square (but note the severe limitations of this model), centered at the non-integer coordinates of the plotted point, and compute its overlap with the four pixels that share the corner closest to that point. Treat that overlap fraction as a grayscale fraction and set each pixel to the largest value for a large number of points approximating a line, or do alpha blending for a small number of discrete points.

How to convert a 3D point cloud to a depth image?

For my work I have to convert a point cloud to a grey scale (depth) image meaning that the z coordinate of each XYZ point in the cloud represents a shade of grey. For mapping a Z coordinate from the [z_min, z_max] interval to the [0..255] interval I used the map function of Arduino:
float map(float x, float in_min, float in_max, float out_min, float out_max)
{ return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; }
With that done I need to write the result to an image, the problem being that the clouds that I have can have millions of points so I can't just write them 1 by 1 to an image in order. Let's say that I have 3000x1000 ordered XY points. How would I do if I wanted to write them to a 700x300 pixels image? I hope the question is clear, thanks in advance for answering.
I have managed to find a solution to my problem. It is a fairy long algorithm for stack overflow but bear with me. The idea is write a vector of XY grey scale points as a pgm file.
Step 1: cloud_to_greyscale - function that converts an XYZ Point Cloud into a vector of XY grey scale points and that receives a cloud as a parameter:
for each point pt in cloud
point_xy_greyscale.x <- pt.x
point_xy_greyscale.y <- pt.y
point_xy_greyscale.greyscale <- map(pt.z, z_min, z_max, 0, 255)
greyscale_vector.add(point_xy_greyscale)
loop
return greyscale_vector
Step 2: greyscale_to_image - function that writes the previously returned vector as a greyscale_image, a class that has a width, a height and a _pixels member corresponding to a double dimensional array of unsigned short usually. The function receives the following parameters: a greyscale_vector (to be turned into the image) and an x_epsilon that will help us delimit the x pixel coordinates for our points, knowing that the x point coordinates are floats (and thus not suitable as array indices).
A little background info: I work on something called widop clouds so in my 3D space x is the width, y is the depth and z is the height. Also worth noting is the fact that y is an integer so for my problem, the height of the image is easy to find: it's y_max - y_min. To find the width of the image, follow the algorithm below and if it isn't clear I will answer any questions and I'm open to suggestions.
img_width <- 0; // image width
img_height <- y_max - y_min + 1 // image height
// determining image width
for each point greyscale_xy_point in greyscale_vector
point_x_cell <- (pt.x - x_min) * x_epsilon * 10
if point_x_cell > img_width
img_width <- point_x_cell + 1
loop
// defining and initializing image with the calculated height and width
greyscale_img(img_width, img_height)
// initializing greyscale image points
for y <- 0 to greyscale_img.height
for x <- 0 to greyscale_img.width
greyscale_img[y][x] = 0
loop
loop
// filling image with vector data
for each point point_xy_greyscale in greyscale_vector
image_x = (point_xy_greyscale.x - x_min) * x_epsilon * 10
image_y = point_xy_greyscale.y - y_min
greyscale_image[image_y][image_x] = point_xy_greyscale.greyscale
loop
return greyscale_image
The only thing left to do is to write the image to the file, but that is easy to do, you can just find the format rules in the previous link related to the pgm format. I hope this helps someone.
EDIT_1: I added a picture of the result. It is supposed to be a railway and the reason it's fairly dark is that there are some objects that are tall so ground objects are darker.
depth image of railway

Coordinates of a pixel between two images

I am looking for a solution to easily compute the pixel coordinate from two images.
Question: If you take the following code, how could I compute the pixel coordinate that changed from the "QVector difference" ? Is it possible to have an (x,y) coordinate and find on the currentImage which pixel it represents ?
char *previousImage;
char *currentImage;
QVector difference<LONG>;
for(int i = 0 ; i < CurrentImageSize; i++)
{
//Check if pixels are the same (we can also do it with RGB values, this is just for the example)
if(previousImagePixel != currentImagePixel)
{
difference.push_back(currentImage - previousImage);
}
currentImage++;
}
EDIT:
More information about this topic:
The image is in RGB format
The width, the height and the bpp of both images are known
I have a pointer to the bytes representing the image
The main objective here is to clearly know what is the new value of a pixel that changed between the two images and to know which pixel is it (its coordinates)
There is not enough information to answer, but I will try to give you some idea.
You have declared char *previousImage;, which implies to me that you have a pointer to the bytes representing an image. You need more than that to interpret the image.
You need to know the pixel format. You mention RGB, So -- for the time being, let's assume that the image uses 3 bytes for each pixel and the order is RGB
You need to know the width of the image.
Given the above 2, you can calculate the "Row Stride", which is the number of bytes that a row takes up. This is usually the "bytes per pixel" * "image width", but it is typically padded out to be divisible by 4. So 3 bpp and a width of 15, would be 45 bytes + 3 bytes of padding to make the row stride 48.
Given that, if you have an index into the image data, you first integer-divide it against the row stride to get the row (Y coordinate).
The X coordinate is the (index mod the row stride) integer-divided by the bytes per pixel.
From what I understand, you want compute the displacement or motion that occured between two images. E.g. for each pixel I(x, y, t=previous) in previousImage, you want to know where it did go in currentImage, and what is his new coordinate I(x, y, t=current).
If that is the case, then it's called motion estimation and measuring the optical flow. There are many algorithms for that, who rely on more or less complex hypotheses, depending on the objects you observe in the image sequence.
The simpliest hypothesis is that if you follow a moving pixel I(x, y, t) in the scene you observe, its luminance will remain constant over time. In other words, dI(x,y,t) / dt = 0.
Since I(x, y, t) is function of three parameters (space and time) with two unknowns, and there is only one equation, this is an ill defined problem that has no easy solution. Many of the algorithms add an additional hypothesis, so that the problem can be solved with a unique solution.
You can use existing libraries which will do that for you, one of them which is pretty popular is openCV.

screen.h header file method confusion

`Obtain the stride (the number of bytes between pixels on different rows)
screen_get_buffer_property_iv(mScreenPixelBuffer, SCREEN_PROPERTY_STRIDE, &mStride)`
I don't understand what the first line meant about having bytes between pixels on different rows. The function is what the stride is obtained through.
If we have a rectangular bunch of pixels (a screen, bitmap, or some such), there must be a way for a program to calculate the position of a pixel. Lets call this sort of bunch of pixels a "surface".
The surface can be split into individual pixels, and we could just put then in a very long row and number then from 0 to some large number (e.g. a 1280 x 1024 screen would have 1310720 pixels). But if you show this long row of pixels on a screen, it makes more sense to talk about lines of pixels that are 1280 pixels long, and have 1024 rows of them.
Now, let's say we want to draw a line from pixels 100,100 to 100,200. We can easily write that as:
int i;
for(i = 100; i < 200; i++)
{
setpixel(surface, 100, 100+i, colour);
}
Now, if we want to implement setpixel, what do we need to do? One thing would be to translate our x, y coordinates (100, 100+i) into a location of our "long row of pixels".
The general formula tends to be (x + y * width) * bytes_per_pixel. So if we have a 32bpp image (four bytes per pixel), that would make (100 + (100+i) * 1280) * 4
However, to make it easier to design the graphics chip there are often limits on things like "the width of a surface must be an even multiple of X", where X is usually 16, 32, 64 or some other power of 2. Sometimes, it has to be a power of two directly (for example textures in early opengl can only be 2^n x 2^n pixels in size - you don't have to USE the entire texture). And this is where stride comes in.
Say we want to have a bitmap of 100 x 100 pixels. But the graphics chip that we use to draw the bitmap to the screen has a rule that you MUST have a even multiple of 32 pixels wide surfaces. So we make something like this
XXXXXXXXXX...
XXXXXXXXXX...
XXXXXXXXXX...
XXXXXXXXXX...
XXXXXXXXXX...
XXXXXXXXXX...
XXXXXXXXXX...
XXXXXXXXXX...
XXXXXXXXXX...
XXXXXXXXXX...
The X's here represent the actual pixels (10 per X) in our bitmap, and the ... 28 pixels of "waste" that we have to have to make the graphics chip happy.
Now the formula of using width doesn't work, because from the software creating the bitmap, the width is 100 pixels. We need to change the math to make up for the "extra space at the end of each row of pixels":
(x + y * stride) * bytes_per_pixel
Now, the stride is 128, but the width is 100 pixels.
Stride here refers to array stride, the number of bytes between memory locations that correspond to the beginning of adjacent rows of an array, in this case of pixels.
In a fully packed array, the stride equals the size of an individual pixel multiplied with the number of pixels in the row. For performance reasons, arrays are frequently aligned so that each row takes a "round" number of bytes, typically an exponent of two. The byte size of the row, aka the stride, cannot be computed from other array parameters and must be known in order to correctly calculate the memory position of an arbitrary pixel.

x,y,z to vector offset

I know this may sound stupid but I'm goin crazy with this XD
I'm loading ad image (with ImageMagick) into a 1D vector, so that I have something like:
012345678...
RGBRGBRGB...
Where 0-. Are obviously the indexes of the vector, and R, G, and B are respectively the red byte, green byte, and blue byte.
So I have a WIDTHxHEIGHTx3 bytes vector.
Now, let's say I want to access the x,y,z byte, where z is the index of the color, which is the transformation formula to have a linear offset into the vector?
This expression produces an index to color component z at pixel (x,y):
((y * WIDTH) + x) * 3 + z
Assumptions are:
Data is placed in row-major order.
No padding/alignment bytes are used between rows.
Assuming your data is stored as a series of rows (not a crazy assumption), you can find byte x,y,z at y*WIDTH*3 + 3*x + z