Effective way to get into image processing with C++? - c++

Recently I was turned on to the opencv programming library for image and data processing, and over the course of trying to get the software to work I've decided I'm simply fed up with how complicated it is to get the libraries onto my computer. Is there another library or framework that allows a user to interact with cameras and image processing in c++ but doesn't require such tedious work to obtain and install as OpenCV?
Edit: The reason I am having a hard time with opencsv is because I do not wish to use an IDE to develop any of my programs, I am trying to learn to use gdb from the cmd line and vim to edit

Could you specify which platform you are using and what problems you encountered?
I suspect that many of your problems are not related to OpenCV per se, but instead are general problems you would have with any C++ lib. E.g. getting a 64-bit compiler, a decent IDE, compiling OpenCV and if needed some of its dependencies. That can actually indeed become a nuissance. What platform are you using? I find that a Linux distribution with a good package repository makes this way easier, since you can very easily setup the required tools and often install many build dependencies via the repository without having to compile them yourself.
If indeed you are having strictly OpenCV-related issues, ITK (http://www.itk.org/) may well be a good alternative.
Best,

You can use this in 8-steps
#include <cv.h>
#include <highgui.h>
using namespace cv;
int main( int argc, char** argv )
{
Mat image;
image = imread( argv[1], 1 );
if( argc != 2 || !image.data )
{
printf( "No image data \n" );
return -1;
}
namedWindow( "Display Image", CV_WINDOW_AUTOSIZE );
imshow( "Display Image", image );
waitKey(0);
return 0;
}
in Linux.
Windows also needs 8-steps.
You can call MATLAB engine from C/C++ . Matlab has image-processing too!

When I did a lot of image processing I would deal with Bitmaps. Read the file into memory and make note of the BITMAPFILEHEADER. There is more information but you could just look up the offset into the pixel data. You could use Directshow as well to get frames from a webcam.
Create a wrapper to expose some user friendly functions like getPixel() etc.
Then I would look up papers + blogs etc to see if I can write the algorithms myself, sometimes it's all too easy passing some image to say a FaceTracking(ImageData data) function.

Related

Decrease in the quality of the image in flycapture

I am using flycapture sdk sample program to capture image form the flycapture.
My problem is that when i capture the image using the flycapture installed application the size of image is about 1.3 - 1.5 Mb. But when the take the same image using my program which consist of flycapture sample program. The size of the image is about 340K to 500K(max).Image format is .tiff
There is reduction in the quality of the image due to which my program is not able to get any valuable information form the image.
Using the following approach to save the image:
FlyCapture2::Camera camera;
FlyCapture2::Image image;
camera.RetrieveBuffer(&image);
ostringstream saveImage;
saveImage << "Image-" << "-" << i << ".tiff";
image.Save(saveImage.str().c_str());
And using the windows application following the approach mentioned in the link:
http://www.ptgrey.com/Content/Images/uploaded/FlyCapture2Help/flycapture/03demoprogram/saving%20images_flycap2.html
Please let me of any other details required
I am not 100% sure about this, since the documentation I found was for Java and not c++, but it is probably very similar.
You are using :
image.Save(saveImage.str().c_str());
to save your image, but are you sure it is saved as a tiff? the documentation (the java one), doesn't go deep into this, I am not sure if it is like OpenCV's imwrite that it automatically deduces the type and does it or not. So you should check that. There was one overload that you can pass the ImageFileFormat... this should be set to the TIFF one.
Another overload let's you specify the TIFF Options... in here you may tune it to have a different compression method. Notice that there is JPEG compression method... which would make something wayyy lighter but lossy... You may try with None, or the one that OpenCV uses LZW.

OpenCV image dimensions without reading entire image

I'm using OpenCV and am reading gigabytes of images -- too much to fit into memory at a single time. However, I need to initialize some basic structures which require the image dimensions. At the moment I'm using imread and then freeing the image right away, and this is really inefficient.
Is there a way to get the image dimensions without reading the entire file, using opencv? If not could you suggest another library (preferably lightweight, seeing as that's all it'll be used for) that can parse the headers? Ideally it would support at least as many formats as OpenCV.
I don't think this is possible in opencv directly.
Although it isn't specified in the docs, Java's ImageReader.getHight (and getWidth) only parse the image header, not the whole image.
Alternatively here is a reasonable looking lightweight library that definitely only checks the headers, and supports a good amount of image formats.
Finally, if you're on Linux the 'identify ' terminal command will also give you the dimensions, which you could then read in programmatically.
You could use boost gil:
#include <boost/gil/extension/io/jpeg_io.hpp>
int main(int argc, char *argv[])
{
//set/get file_path
auto dims = boost::gil::jpeg_read_dimensions(file_path);
int width = dims.x;
int height = dims.y;
}
You will have to link against libjpeg, by adding -ljpeg flag to the linker. You can get some more information here.

SDL embed image inside program executable

Is it possible to embed an image within a program using SDL which can be used at run time.
For example, I have a program which brings up a splash screen on startup containing the logo and copyright information. Rather than having this image in a bitmap file and using SDL_LoadBMP to load it to a SDL_Surface. I would like to have the image embedded in the program binary, to stop someone potentially changing the splash image and copyright name.
Does anyone have any suggestions on ways to do this? Example code would be great.
Embedding a file in an executable is easy but there are some gotchas, there are several ways to do it including some portable and non-portable ways.
Using #embed
This will reportedly be part of C23. It may be on track to appear in C++26 as well. Check whether your compiler supports this feature. In the future, this may be the most portable and straightforward way to embed binary data.
static const unsigned char IMAGE_DATA[] = {
#embed "myimage.bmp
};
See WG14 n2592 for the feature proposal.
Advantages: simplest, easiest
Disadvantages: your compiler probably doesn’t support this yet
Convert the image to C code
Write a script to convert the image to a constant array in C. The script would look something like this in Python:
#!/usr/bin/env python3
print("static const unsigned char IMAGE_DATA[] = {{{}}};".format(
",".join(str(b) for b in open("myimage.bmp", "rb").read())))
Just pipe the output to a *.h file and include that file from one other file. You can get the size of the file with sizeof(IMAGE_DATA).
Advantages: portable
Disadvantages: requires Python to be installed, does not work if array is too large for compiler, requires adding a custom step to the build system
Convert the image to an object file
This is more platform-dependent. On platforms with GNU binutils toolchains (e.g. Linux) you can use objcopy, I think bin2obj works on Microsoft toolchains.
Advantages: works everywhere
Disadvantages: non-portable, requires adding a custom step to the build system, the custom step might be tricky to get right
On GNU binutils toolchains, with objcopy
The objcopy program lets you specify binary as the input format, but then you need to specify the architecture explicitly... so you will have to modify the command for i386 and x64 versions of your executable.
$ objcopy --input binary --output elf32-i386 --binary-architecture i386 \
myimage.bmp myimage.o
You can get the data from C by using the following declarations:
// Ignore the fact that these are char...
extern char _binary_myimage_bmp_start, _binary_myimage_bmp_end;
#define MYIMAGE_DATA ((void *) &_binary_myimage_bmp_start)
#define MYIMAGE_SIZE \
((size_t) (&_binary_myimage_bmp_end - &_binary_myimage_bmp_start))
Use an assembler directive
Paradoxically, embedding a static file is fairly easy in assembler. Assemblers often have directives like .incbin (which works with GAS and YASM).
Advantages: works everywhere
Disadvantages: non-portable, assembler syntax is different between platforms
(Windows) Embed the file as a resource
On Windows, you can embed resources in an EXE and then get the resources using library calls.
Advantages: probably easiest if you are on Windows
Disadvantages: only works on Windows
You can export the image as .xpm format (in gimp) and include it to your code. But you will need SDL_Image.h to load it as SDL_Surface.
As it is in this doc, is really simple:
//To create a surface from an XPM image included in C source, use:
SDL_Surface *IMG_ReadXPMFromArray(char **xpm);
A example in C/C++:
#include <SDL/SDL.h>
#include "test.xpm"
#include <SDL/SDL_image.h>
SDL_Surface *image;
SDL_Surface *screen;
int main(int argc, char **argv)
{
SDL_Init(SDL_INIT_EVERYTHING);
screen = SDL_SetVideoMode(800,600,32,SDL_SWSURFACE);
image = IMG_ReadXPMFromArray(test_xpm); //the .xpm image is a char array. "test_xpm" is the name of the char array
SDL_Rect offset;
offset.x = 0;
offset.y = 0;
SDL_BlitSurface(image,NULL,screen,&offset);
SDL_Flip(screen);
SDL_Delay(5000);
return 0;
}
I hope this helps.
With gimp you can save a image as c code.

converting a binary stream into a png format

I will try to be clear ....
My project idea is as follow :
I took several compression algorithms which I implemented using C++, after that I took a text file and applied to it the compression algorithms which I implemented, then applied several encryption algorithms on the compressed files, now I am left with final step which is converting these encrypted files to any format of image ( am thinking about png since its the clearest one ).
MY QUESTION IS :
How could I transform a binary stream into a png format ?
I know the image will look rubbish.
I want the binary stream to be converted to a an png format so I can view it as an image
I am using C++, hope some one out there can help me
( my previous thread which was closed )
https://stackoverflow.com/questions/5773638/converting-a-text-file-to-any-format-of-images-png-etc-c
thanx in advance
Help19
If you really really must store your data inside a PNG, it's better to use a 3rd party library like OpenCV to do the work for you. OpenCV will let you store your data and save it on the disk as PNG or any other format that it supports.
The code to do this would look something like this:
#include <cv.h>
#include <highgui.h>
IplImage* out_image = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, bits_pr_pixel);
char* buff = new char[width * height * bpp];
// then copy your data to this buff
out_image->imageData = buff;
if (!cvSaveImage("fake_picture.png", out_image))
{
std::cout << "ERROR: Failed cvSaveImage" << std::endl;
}
cvReleaseImage(&out_image);
The code above it's just to give you an idea on how to do what you need using OpenCV.
I think you're better served with a bi-dimensional bar code instead of converting your blob of data into a png image.
One of the codes that you could use is the QR code.
To do what you have in mind (storing data in an image), you'll need a lossless image format. PNG is a good choice for this. libpng is the official PNG encoding library. It's written in C, so you should be able to easily interface it with your C++ code. The homepage I linked you to contains links to both the source code so you can compile libpng into your project as well as a manual on how to use it. A few quick notes on using libpng:
It uses setjmp and longjmp for error handling. It's a little weird if you haven't worked with C's long jump functionality before, but the manual provides a few good examples.
It uses zlib for compression, so you'll also have to compile that into your project.

Working with images in C++ or C

The first thing is that I am a beginner. Okay?
I've read related answers and questions, but please help me with this problem:
How can I open an JPEG image file in C++, convert it to a grayscale image, get its histogram, resize it to a smaller image, crop a particular area of it, or show a particular area of it?
For these tasks, is C or C++ faster in general?
What libraries are simplest and fastest? The running time is very important.
Thanks.
here is an example using magick library.
program which reads an image, crops it, and writes it to a new file (the exception handling is optional but strongly recommended):
#include <Magick++.h>
#include <iostream>
using namespace std;
using namespace Magick;
int main(int argc,char **argv)
{
// Construct the image object. Seperating image construction from the
// the read operation ensures that a failure to read the image file
// doesn't render the image object useless.
Image image;
try {
// Read a file into image object
image.read( "girl.jpeg" );
// Crop the image to specified size (width, height, xOffset, yOffset)
image.crop( Geometry(100,100, 100, 100) );
// Write the image to a file
image.write( "x.jpeg" );
}
catch( Exception &error_ )
{
cout << "Caught exception: " << error_.what() << endl;
return 1;
}
return 0;
}
check many more examples here
well for basic image manipulations you could also try Qt's QImage class (and other). This gives you basic functionality for opening, scaling, resizing, cropping, pixel manipulations and other tasks.
Otherwise you could as already said use ImageMagick or OpenCV. OpenCV provides a lot of examples with it for many image manipulation/image recognition tasks...
Hope it helps...
There are many good libraries for working with images in C and C++, none of which is clearly superior to all others. OpenCVwiki, project page has great support for some of these tasks, while ImageMagickwiki, project page is good at others. The JPEG group has its own implementation of JPEG processing functions as well. These are probably good resources to start from; the API documentation can guide you more specifically on how to use each of these.
As for whether C or C++ libraries are bound to be faster, there's no clear winner between the two. After all, you can always compile a C library in C++. That said, C++ libraries tend to be a bit trickier to pick up because of the language complexity, but much easier to use once you've gotten a good feel for the language. (I am a bit biased toward C++, so be sure to consider the source). I'd recommend going with whatever language you find easier for the task; neither is a bad choice here, especially if performance is important.
Best of luck with your project!
If running time is really important thing then you must consider image processing library which offloads processing job to GPU chip, such as:
Core Image (Osx)
OpenVIDIA (Windows)
GpuCV (Windows, Linux)
libgd is about the easiest, lightest-weight solution.
gdImageCreateFromJpeg
gdImageCopyMergeGray
gdImageCopyResized
Oh, and it's all C.