Show image on windows using imagemagick - c++

I am using ImageMagick for a few modifications in images. My requirement is to capture desktop, update the captured image and show in the window (Canvas, Form or simple Win32 API image).
Everything working perfectly except showing a converted image on the window.
As per this discussion, display functionality of image magick is only supported by Linux and Mac (Please correct me if anything wrong).
The same forum suggested to use im_display to show the image on window. However, I am not able to locate any function related im_display() in the image magick library (Please correct me here if any additional include required).
When I am trying to call following code from visual studio then getting "delegate library support not built-in '' (X11) # error/display.c/DisplayImages/16224" error:
int main(int argc, char **argv)
{
try
{
Magick::InitializeMagick(NULL);
Image screen("screenshot:");
screen.display();
}
catch (exception &error_)
{
cout << "Caught exception: " << error_.what() << endl;
return 1;
}
return 0;
}
So the following are two primary questions:
Is it possible to show an image using image magick on windows (Form or canvas or win32)
If it's not possible then HBITMAP will help to render an image on windows. However, I am not able to find a way to convert Image Magick data to BITMAP. Can you please provide suggestions?

Related

Can't save Images using QImage

I wish to use QImage in Qt to load and save images. While I can load an image, for whatever reason it wont let me save the image.
So I started writing a simple code, made a simple png test file using paint, put it into the same folder as the project itself.
#include <QImage>
#include <iostream>
int main(){
QImage image;
image.load("test.png");
if (image.isNull()){
std::cout << "ERROR!\n";
}
else{
std::cout << "IMAGE LOADED!\n";
}
image.save("test1.png");
return 0;
}
During running the program I get the message of "IMAGE LOADED!" from the application output, however when I check the folder I expect the same image saved as test1.png, which doesn't appear at all.
So, how do I actually save an image? What did I miss?
In the other comments mentioned the image got saved into the working directory, which is not the same as the folder where the project is located.
In my specific case I got the image by adding a full path to the project like
int i = image.save("C:\\Users\\UserName\\Documents\\QT\\testing_ground_cpp\\" + string);
to find the image.
Ideally I should directly access with the working directory.

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 let user choose to open image

I am trying to create a simple image processor in opencv. I so far have experimented to open a set image from file with this code.
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
Mat im = imread("c:/image.jpg");
if (im.empty())
{
cout << "Cannot load image!" << endl;
return -1;
}
imshow("Image", im);
waitKey(0);
}
As this only allows a set image file to be open, how could i modify it so it allows the user to select an image?
Is this possible or can i only load a set image from file?
Thanks.
If you want your program to run in console only, let the user to input the path of the image file ( or may be using command line arguments).
If you want to make it GUI application, (some fancy window will show up when you click a "Open File" button ) then you have to learn some GUI programming. Choose some GUI programming tool depending on your platform ( Windows, Linux etc) or go for cross platform ( Give a try to Qt )
If you want the user to be able to browse for an image on their computer, you can use the open file dialog box. You can find a sample on MSDN.

OpenCV displaying avi file encoded in I420

I am trying to write a video processing application using OpenCV 2.4.2 (in Visual C++ 2010 Express on Windows 7) but I am having trouble displaying certain AVI files. Most display correctly, but when I use an AVI file encoded in I420 format all I get is a striped pink image for every frame (it displays correctly in regular media players).
Output displayed: http://i.imgur.com/BOu6c.png?1
Currently, I am using the C++ API, but the same thing happens when I use the C API (code from this page: http://nashruddin.com/how_to_play_avi_files_with_opencv). I find this strange, because in most answers on this site and resources on the web, they explicitly recommend to use the I420 encoding. Does anyone know what could be causing this or how to fix it?
Here is a trimmed down version of the code I am using:
int main(int argc, char** argv){
string fname = "test.avi";
VideoCapture capture(fname);
if(!capture.isOpened()){
cerr << "error opening " << fname << endl;
return -1;
}
Mat frame;
namedWindow("output");
double rate = capture.get(CV_CAP_PROP_FPS);
int delay = 1000/rate;
while(true){
if(!capture.read(frame)) break;
cv::imshow("output", frame);
if(waitKey(delay) >= 0) break;
}
capture.release();
return 0;
}
I am using is the pre-compiled version of OpenCV if that makes a difference (http://sourceforge.net/projects/opencvlibrary/).
Ok, so I managed to test on a few more computers. One just crashed and, on another, the video played fine. It turns out that it was a problem with FFMPEG being enabled in the default OpenCV compilation having problems with the uncompressed AVI. Recompile OpenCV with FFMPEG disabled or just use a different codec to compress the video.

Problem with iterating over a lots of images in OpenCv with mac os

I'm trying to iterator over some directories containing approximately 3000 images. I load the image. If the image is loaded I release it.
That is the smallest program that I can write to reproduce the error.
After loading and releasing 124 images the program stops loading images. I think this a memory issue but I don't understand what exactly causes the program to stop loading images.
I'm using OpenCV on my Mac. I don't know how exactly I can figure out which version I'm using.
Here is the Code from my project.
bool FaceDetectionStrategy::detectFace(std::string imagePath) {
IplImage *img = cvLoadImage(imagePath.c_str(), CV_LOAD_IMAGE_COLOR);
if (img) {
std::cout << "Image loaded " << imagePath << std::endl;
cvReleaseImage(&img);
} else {
std::cout << "Image not loaded " << imagePath << std::endl;
}
return true;
}
This method is called for every image in the directorys I'm iterating through. After 124 images the if(img) part evaluates to false and the else branch is executed. If I try to load images from other parts of the program later on they also won't load.
Edit it is not a memory issue. Mac Os standard max open files is 256 after changing it to 512 I can open 251 images. so it seems that OpenCV doesn't closes the image files after loading them.
Searching the bugtracker from OpenCv showed this answer to the problem: cvLoadImage with Mac ImageIO leaves file handles open.
It seems that this is a bug in the OpenCV mac implementation and the only way to solve it is to install a newer version of OpenCV.
EDIT installing the last version of OpenCV from the repository trunk solves the problem. Sometimes it helps checking the BugTracker of the frameworks you are using...
Behavior concerning memory rarely has to do with a consistent number, in my experience. The only way it could be that consistent is if there is some sort of internal limit in cvLoadImage that happens to be the not-very-common number 124. But your logic seems fine to me, that your images should be released.
More likely, since I assume your directories aren't changing between tests, that 125th image is bad.
Have you verified that the image you are trying to load actually exists? If it does (which it probably does), check that the image file format is supported by OpenCV. If that is also true, make sure the file is not corrupted by opening it with another editor.
You can have OpenCV help you out with errors. Use cvGetErrStatus() to check if there was an error, then use cvErrorStr() to get a textual description of it. You can do something like this:
// I would recommend putting this in a file, like CVUtility.h
#include <exception>
void check_CV_Error(void)
{
int errorCode = cvGetErrStatus();
if (errorCode) // I'm assuming 0 means no reportable error
{
throw std::runtime_error(cvErrorStr(errorCode));
// std::cerr << cvErrorStr(errorCode);
// ^ if you would rather not use exceptions
}
}
Your code then becomes:
bool FaceDetectionStrategy::detectFace(std::string imagePath) {
IplImage *img = cvLoadImage(imagePath.c_str(), CV_LOAD_IMAGE_COLOR);
if (img) {
std::cout << "Image loaded " << imagePath << std::endl;
cvReleaseImage(&img);
} else {
std::cout << "Image not loaded " << imagePath << std::endl;
check_CV_Error(); // find reason for error
}
return true;
And that will throw an exception for you to catch and log, and possibly react on. (Or print the error to console if you use the std::cerr version)