My question is pretty simple, suppose I have an image and I want to load it into my program so that I can get the color of each pixel. How could I do that? In a nutshell I want a method that gives me the color of a pixel.
struct color{
double r, g, b;
color(){}
color(float red, float green, float blue){r = red; g = green; b = blue;}
};
color GetPixel(string imageName, int x, int y){
//if(x < 0 || x >= width of image) return color(0,0,0);
//if(y < 0 || y >= height of image) return color(0,0,0);
//do stuff
return colorForPixelXY;
}
Preferably I would like to do it natively, without using any external libs.
The STB image library is a single file, header only "library" that you can include and use in your project scott free. It's sort of an industry standard for cases like yours. Highly recommended.
https://github.com/nothings/stb
That said, reading a PNM/PPM file is very easy thing to do in C++ as it is basically a text file. Any image package can take your BMP,JPG and save it to PNM that you can even include in your executable binary.
read PPM file and store it in an array; coded with C
Related
I have this image:
I have the following functions:
void DrawPixel(int x, int y, unsigned char r, unsigned char g, unsigned char b);
void ReadPixel(GLint x, GLint y, unsigned char &r, unsigned char &g, unsigned char &b);
Objective
Remove the small shapes of the image, there are 4 small shapes in the image, I want to remove them. One way to do this would be by how many red pixels each shape has, if one shape has less than 200 red pixels for example, I'll remove it from the image by painting it in black. This is just a form of solution that I imagined, if anyone has any other alternative it will be welcome.
What I've tried
void RemoveLastNoises(){
int x,y;
int cont = 0;
unsigned char r,g,b;
int xAux;
for(y=0;y<NewImage.SizeY()-0;y++){
for(x=0;x<NewImage.SizeX()-0;x++){
NewImage.ReadPixel(x,y,r,g,b);
if(r == 255){
cont = 0;
while(r == 255){
NewImage.ReadPixel(x+cont,y,r,g,b);
cont = cont + 1;
}
if(cont < 300){
NewImage.DrawPixel(x,y,255,255,255);
}
}
xAux = x;
x = x+cont;
}
x = xAux;
}
}
This works, but only counts how many red pixels it has in a row (x), I found it interesting to put it here as a reference. Anyway, any idea to remove the small shapes will be welcome.
Note:The larger shapes are not to be modified, the height and width of the image is larger, I decrease the dimensions for the question to be readable.
There is a set of nonlinear filters that are called morophological filters.
They use "and" and "or" combination to create filter masks.
What you need to do is implement a closing. OpenGL does not privde such functions thus, you have to write the code on your own. To do so you
If they are always red just use the red channel as grey-scale image
Create a binary image from the created image
Inverse the image from 2
Create a filter mask with '1's that is large enough to cover the small parts you want to rease
Do A Dilation (https://en.wikipedia.org/wiki/Dilation_(morphology)) on the image with the filter mask
Do an Erosion (https://en.wikipedia.org/wiki/Erosion_(morphology)) on the image with the same filter mask or a slightly smaller one
Invert the image again
5 and 6 are describing a "Closing" https://en.wikipedia.org/wiki/Closing_(morphology)
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I'm a first year engineering student and I'm working on a end of term project. Due to tight deadlines, I would like to avoid rummaging through image processing libraries. We (my group mates) need to find the easiest implementable method to get an integer for the number of dark pixels from an image. I have read many other posts regarding image processing, but they are much more complicated than we need. Is there an easy way to do this? It is important that it is easy because this is only a small part of our project and there can't be too much time committed to this.
As for languages, I would prefer to use C++.
On a side note, any exceptional help given would be cited in our report (just mention the name you want to be cited as and you'll go down in history). It would also give us time to sleep. Sleep is to engineering students what cake is to fat kids.
Here is it done in Qt (not image processing but application library)
#include <QImage>
#include <QColor>
uint countDarkPixels(QString filename, quint8 threshold) {
QImage img(filename);
uint darkPixels = 0;
for (int x = 0; x < img.width(); ++x) {
for (int y = 0; y < img.height(); ++y) {
QColor color(img.pixel(x, y));
if (color.toHsl().lightness() < threshold) darkPixels++;
}
}
return darkPixels;
}
Works for other formats besides JPG too. It uses conversion to HSL which may not be very fast, but you said "easy" not "fast".
There are two stages to this:
Load an image from a file.
Determine how many pixels in that image are "dark".
The first stage isn't too difficult - you could either use a pre-existing library, such as DevIL or FreeImage, or write your own - this and this should be enough to get you started.
Once you've loaded the image into your program somehow, you'll need to loop over the pixel data and count the number of "dark" pixels. Let's say you have an image structure that looks like this:
typedef struct
{
int w;
int h;
unsigned char *data;
} image_s;
For simplicity, let's make the following assumptions:
The image is stored in 24-bit, RGB format, so that each pixel is represented as three unsigned bytes like this: RGBRGBRGB.
A "dark" pixel is one where (R+G+B)/3 < 10
Given the above, you would simply need to loop through each pixel within the image structure like so:
int count_dark_pixels(image_s *img)
{
int dark_pixels, i;
for (dark_pixels = 0, i = 0; i < img->w * img->h; ++i)
{
int r = img->data[(i*3)+0];
int g = img->data[(i*3)+1];
int b = img->data[(i*3)+2];
if ((r+g+b)/3 < 10) { ++dark_pixels; }
}
return dark_pixels;
}
Uncompress the jpeg, get the Y channel pixel data (these values are the luminosity of each pixel), count the dark pixels in that. I don't think you need the U and V channels, these are used to reconstruct the colour information.
Working RGB may be a pain, but it all depends on what you mean by a 'dark' pixel.
JPEG images are usually encoded using the YCbCr color space. Rather than Red, Green, Blue the three components are Darkness, Blueness, and redness. The Y component is then a black and white version of the color image.
You can then determine the darkness of any point by examining the value of the Y component of the image. You can set some threshold to determine a dark pixel.
I have an array with raw RGB values in it, and I need to write these values to a JPEG file. Is there an easy way to do this?
I tried:
std::ofstream ofs("./image.JPG", std::ios::out | std::ios::binary);
for (unsigned i = 0; i < width * height; ++i) {
ofs << (int)(std::min(1.0f, image[i].x) * 255) << (int)(std::min(1.0f, image[i].y) * 255) << (int)(std::min(1.0f, image[i].z) * 255);
}
but the format isn't recognized.
If you're trying to produce an image file you might look at Netpbm. You could write the intermediate format (PBM or PAM) fairly simply from what you have. There are then a large number of already written programs that will generate many types of images from your intermediate file.
WOH THERE!
JPEG is MUCH more complicated than raw RBG values. You are going to need to use a library, like LIBJPEG, to store the data as JPEG.
If you wrote it yourself you'd have to:
Convert from RGB to YCbCr
Sample the image
Divide into 8x8 blocks.
Perform the DCT on each block.
Run-length/huffman encode the values
Write these values in properly formatted JPEG blocks.
You could use Boost GIL: it's free, portable (it's part of Boost libraries), usable across a broad spectrum of operating systems (including Windows).
Popular Linux and Unix distributions such as Fedora, Debian and NetBSD include pre-built Boost packages.
The code is quite simple:
#include <boost/gil/extension/io/jpeg_io.hpp>
const unsigned width = 320;
const unsigned height = 200;
// Raw data.
unsigned char r[width * height]; // red
unsigned char g[width * height]; // green
unsigned char b[width * height]; // blue
int main()
{
boost::gil::rgb8c_planar_view_t view =
boost::gil::planar_rgb_view(width, height, r, g, b, width);
boost::gil::jpeg_write_view("out.jpg", view);
return 0;
}
jpeg_write_view saves the currently instantiated view to a jpeg file specified by the name (throws std::ios_base::failure if it fails to create the file).
Remember to link your program with -ljpeg.
I have a mesh (with color) loaded and want to write it to a .ply file and store the rgb information as well. I currently have the code below, which uses the vtkPLYWriter class, but this just saves the vertices and not the RGB info. Is there a built in way to do this?
Code
vtkSmartPointer<vtkTransformPolyDataFilter> rotate_and_save_mesh(vtkSmartPointer<vtkPLYReader> mesh_reader, double rotation_angle, double x, double y, double z,
std::string& out_name, bool should_write = true){
vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New();
transform->RotateWXYZ(rotation_angle, x, y, z);
vtkSmartPointer<vtkTransformPolyDataFilter> transformFilter = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
transformFilter->SetTransform(transform);
transformFilter->SetInputConnection(mesh_reader->GetOutputPort());
transformFilter->Update();
if(should_write){
vtkSmartPointer<vtkPLYWriter> writer = vtkSmartPointer<vtkPLYWriter>::New();
writer->SetInputConnection(transformFilter->GetOutputPort());
writer->SetFileName(out_name.c_str());
writer->Write();
}
return transformFilter;
}
This is very awkward. Unlike vtkPolyDataXMLWriter and most other VTK writers, you must specify
plyWriter->SetArrayName("Colors");
where your color array was created/named like this:
vtkSmartPointer<vtkUnsignedCharArray> colors =
vtkSmartPointer<vtkUnsignedCharArray>::New();
colors->SetNumberOfComponents(3);
colors->SetName("Colors");
I want to manipulate JPEG images with C++ using the decoder Mini Jpeg Decoder.
The problem is: I want to read pixel per pixel, but the decoder only returns an imageData-array, similar as libjpeg does.
I can't make a method like this:
char getPixel(char x, char y, unsigned char* imageData)
{
//...???
}
The return (the char variable) should contain the luminance of the pixel.
(I work with grayscale images...)
How can I solve this problem?
As far as I can tell, the Decoder class delivers a byte array of color values with the GetImage() method. So you could write a function that looks like this:
char getLuminance(Decoder* dec, int x, int y) {
if(x < 0 || y < 0 || x >= dec->GetWidth() || y >= dec->GetHeight()) {
throw "out of bounds";
}
return dec->GetImage()[x + y * dec->GetWidth()];
}
I'm uncertain of the pixel layout, so maybe the array access is not right. Also this only works for grey-scale images, or else you would get the luminance of the Red color value at the position only. HTH