I just want to display this "img1.jpg" image in a c++ project with using opencv libs for future processes, but it only displays an empty gray window. What is the reason of this. Is there a mistake in this code? please help!
Here is the code;
Mat img1;
char imagePath[256] = "img1.jpg";
img1 = imread(imagePath, CV_LOAD_IMAGE_GRAYSCALE);
namedWindow("result", 1);
imshow("result", img1);
Thanks...
I had the same problem and solved putting waitKey(1); after imshow(). The OpenCV documentation explains why:
This function is the only method in HighGUI that can fetch and handle
events, so it needs to be called periodically for normal event
processing, unless HighGUI is used within some environment that takes
care of event processing.
Thanks #b_froz.
For more detials about this issue,you can refer to: http://docs.opencv.org/2.4/modules/highgui/doc/user_interface.html#imshow
Note This function should be followed by waitKey function which displays the image for specified milliseconds. Otherwise, it won’t display the image. For example, waitKey(0) will display the window infinitely until any keypress (it is suitable for image display). waitKey(25) will display a frame for 25 ms, after which display will be automatically closed. (If you put it in a loop to read videos, it will display the video frame-by-frame)
So,not only waitkey(1)could be put after imshow(),but also waitkey(0) or waitkey(other integers).Here is the explanation of the function waitkey() : http://docs.opencv.org/2.4/modules/highgui/doc/user_interface.html#waitkey
Are you importing the correct library ?
This is other very easy way to load one image:
#define CV_NO_BACKWARD_COMPATIBILITY
#include <cv.h>
#include <highgui.h>
#include <math.h>
main(){
IplImage* img = cvLoadImage("yourPicture.jpg");
cvNamedWindow("Original", 1);
cvShowImage("Original", img);
}
I think you have openCV correctly installed, so yo can type this (Ubuntu):
g++ NameOfYourProgram.cpp -o Sample -I/usr/local/include/opencv/ -L/usr/local/lib -lcv -lhighgui ./sample
The problem you are having is due to the type of your Mat img1. When you load your image with the flag CV_LOAD_IMAGE_GRAYSCALE, the type of your Mat is 0 (CV_8UC1), and the function imshow() is not able to show the image correctly.
You can solve this, converting your Mat to type 16 (CV_8UC3):
img1.convertTo(img1,CV_8UC3);
and then show it with imshow():
imshow("result", img1);
I hope this help.
Related
I have an app that loads an image in a QPixmap, which changes depending on the user's request.
Not all images have the same format, or the same size, some vertical and others horizontal.
I am using Qt5.14.2, with MinGW 7.3.0 32-bit and Qt Creator 4.11.1. in W10.
On a machine running W8.1 and the same version of Qt, MinGW and QtCreator have been working fine.
The first image loads perfectly, but if I change it, it already returns the empty QPixmap.
I have done different tests to be able to load the image, resizing the QPixmap (with fixed dimensions and with those of the image),
saving the QImage to a file and loading it from the file putting the PNG format, etc.
I have been able to check that the images are generated correctly, to rule out that it would be a problem when converting the data to QImage.
Any idea what is happening? I can't put the code because it's quite an extensive app, so I'll narrow it down to where the problem is
My_class.h:
QPixmap pixmap;
My_class.cpp:
int w=num_celdas_imagen_x*128;
int h=num_celdas_imagen_y*128;
unsigned char *data =(unsigned char *)malloc(w*h*3);
// filling data
QImage img = QImage((unsigned char *)data,w,h,QImage::Format_RGB888);
// At this point I have been able to check that the image is generated correctly
this->pixmap = QPixmap::fromImage(img);
// At this point the QPixmap is null (except with the first image, which loads fine)
Thanks
Sorry for lengthier explanation. As am new to Open want to give more details with example.
My requirement is to find the delta of 2 static images, for this am using the following technique:
cv::Mat prevImg = cv::imread("prev.bmp");
cv::Mat currImg = cv::imread("curr.bmp");
cv::Mat deltaImg;
cv::absdiff(prevImg,currImg,deltaImg);
cv::namedWindow("image", CV_WINDOW_NORMAL);
cv::absdiff(prevImg,currImg,deltaImg);
cv::imshow("image", deltaImg);
And in the deltaImg, am getting the difference between the images, but it includes the background of the first image also. I know i have to remove the background using BackgroundSubtractorMOG2, but am unable to understand this class usage as most of the examples are based on webcamera captures.
Please note that my images are static (Screen shots of the desktop activity).
Please guide me in resolving this issue, some sample code will be helpful.
Note I want to calculate delta in RGB.
Detailed Explination:
Images are at : https://picasaweb.google.com/105653560142316168741/OpenCV?authkey=Gv1sRgCLesjvLEjNXzZg#
Prev.bmp: The previous screen shot of my dektop
curr.bmp: The current screen shot of my desktop
The delta between the prev.bmp and curr.bmp, should be the startup menu image only, please find the image below:
The delta image should contain only the startup menu, but even contains the background image of the prev.bmp, this background i want to remove.
Thanks in advance.
After computing cv::absdiff your image contains non-zero values for each pixel that changed it's value. So you want to use all image regions that changed.
cv::Mat deltaImg;
cv::absdiff(currImg,prevImg,deltaImg);
cv::Mat grayscale;
cv::cvtColor(deltaImg, grayscale, CV_BGR2GRAY);
// create a mask that includes all pixel that changed their value
cv::Mat mask = grayscale>0;
cv::Mat output;
currImg.copyTo(output,mask);
Here are sample images:
previous:
current:
mask:
output:
and here is an additional image for the deltaImg before computing the mask:
Problems occur if foreground pixels have the same value as background pixel but belong to some other 'objects'. You can use cv::dilate operator (followed by cv::erode) to fill single pixel gaps. Or you might want to extract the rectangle of the start menu if you are not interested in all the other parts of the image that changed, too.
I wrote an OPENCV project in VS2010 and the results were not the ones as I expected so I ran the debugger to see where is the problem. When I wanted to see the data inside the image loaded I didn't know how to do it so if I want to see the data inside my images what should I do?
It is pretty simple in matlab for seeing different channel of an image i.e.
a=imread('test.jpg');
p1 = a(:,:,1)
p2 = b(:,:,2)
.
.
In opencv I wrote the same thing but I don't know how to see all the element at once just like Matlab.
a= imread("test.jpg")
split(a,planes);
vector<Mat> T1;
T1 = planes[0];
// How can I see the data inside T1 when debugging the code ?
I think this is what you are looking for - it's a great Visual Studio add-on
https://bitbucket.org/sergiu/opencv-visualizers
Just download the installer, make sure VS is closed, run it, re-open VS and voila! Now, when you point to an OpenCV data structure, all kinds of nice info is showed.
Limitations: I saw some problems with multichannel images (it only shows the first channel) and it also has trouble displaying large matrices. If you want to see raw data in a big matrix, you can use the old good VS trick with debug variables: Stop at a breakpoint, go to Watch tab, and write there
((float*)myMat.data) ,10
Where float is the matrix type, myMat is your matrix, and 10 is the number of values you want to print. It will display the first 10 values at the memory location of myMat.data. If you do not correctly choose the data type, you'll see garbage. In my example, myMat is of type cv::Mat.
And never forget the power of visualizers:
imshow("Image", myMat);
If your data fits into an image. You can use the contrib module's colormap to enhance your visualizers.
I can't actually believe that nobody suggested Image Watch yet. It's the most amazing add-in ever. It shows you a view with all your Mat variables (images (gray and color), matrices) while debugging, there's useful stuff like zooming or contrast-stretching and you can even apply more complex functions directly in the plugin in real-time. It makes debugging of any kind of image operations a breeze and it's immensely helpful if you do calculations and linear algebra stuff with your cv::Mat matrices.
I recommend to use a NativeViewer extension. It actually displays the content of an image in a preview window, not only the properly formatted info.
If you don't want to use a plug-in or extension to Visual Studio, you can access the elements one by one in the debugging watch tab by typing this:
T1.data[T1.step.buf[0]*i + T1.step.buf[1]*j];
where i is the row you want to look at and j is the column.
after downloading imagewatch use the command in watch window
(imagesLoc._Myfirst)[0]
index of image in the vector
You can use the immediate window and the extenshion method like this one
/// <summary>
/// Displays image
/// </summary>
public static void Display (this Mat m, Rect rect = default, string windowName = "")
{
if (string.IsNullOrEmpty(windowName))
{
windowName = m.ToString();
}
var img = rect == default ? m : m.Crop(rect);
double coef = Math.Min(1600d / img.Width, 800d / img.Height);
Cv2.ImShow(windowName, img.Resize(new Size(coef * img.Width, (coef * img.Height) > 1 ? coef * img.Height : 1)));
Cv2.WaitKey();
}
Then you stop at a breakpoint and call yourImage.Display() in the immediate window.
If you can use CLion you can utilize the OpenCV Image Viewer plugin, which displays matrices while debugging just on click.
https://plugins.jetbrains.com/plugin/14371-opencv-image-viewer
Disclaimer: I'm an author of this plugin
I am working on a program using the OpenCV library (though I am quite a noob on it). One of the things I need to do is to draw on the image. I looked at the OpenCV drawing functions and they all seem pretty simple (Circle, Line, etc), however the program won't compile! It says this to be exact: error C3861: 'Line': identifier not found.
Is there something I haven't installed? I used the tutorial on http://opencv.willowgarage.com/wiki/VisualC%2B%2B_VS2008 to install OpenCV on Visual Studio 2008 and so far this is the only real problem I have.
Please help me! I need this program working as soon as possible!
The function to draw a line in the OpenCV C API is named cvLine, not Line.
I think you have fallen victim of the following common mistake:
C includes are in #include <opencv/core.h> etc, whereas
C++ includes are:
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <oppencv2/highgui/highgui.hpp>
Include these for drawing and showing the image. Use using namespace cv; then
you don't have to write cv::line just line and everything will be working fine.
I had to battle with the very same problem when I began. ;)
(And btw use cv::Mat for c++.)
You can now easily paint on OpenCV images. For this you need to call the setMouseCallback(‘window_name’,image_name) function on opencv. After that you can easily handle the Mouse Callback Function upon your images. Then you need to detect the cv2.EVENT_LBUTTONDOWN, cv2.EVENT_MOUSEMOVE and cv2.EVENT_LBUTTONUP events. By checking the proper boolean condition you need to decide how you like to interact with the OpenCV images.
def paint_draw(event,former_x,former_y,flags,param):
global current_former_x,current_former_y,drawing, mode
if event==cv2.EVENT_LBUTTONDOWN:
drawing=True
current_former_x,current_former_y=former_x,former_y
elif event==cv2.EVENT_MOUSEMOVE:
if drawing==True:
if mode==True:
cv2.line(image,(current_former_x,current_former_y),(former_x,former_y),(0,0,255),5)
current_former_x = former_x
current_former_y = former_y
elif event==cv2.EVENT_LBUTTONUP:
drawing=False
if mode==True:
cv2.line(image,(current_former_x,current_former_y),(former_x,former_y),(0,0,255),5)
current_former_x = former_x
current_former_y = former_y
return former_x,former_y
For details you can see link: How to Paint on OpenCV Images and Save the Image
Output:
I am developing a Windows API application without using MFC.
I am using standard Windows libraries.
How do I draw a PNG image in a window?
Help me with some sample code.
I have tried some codes which are available on the Internet, but all are using MFC.
Take a look at this StackOverflow question. It offers several options which should meet your needs.
Adapted from MSDN:
#include <windows.h>
#include <gdiplus.h>
#include <stdio.h>
using namespace Gdiplus;
void draw()
{
// start up GDI+ -- only need to do this once per process at startup
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
Rect rect(20,20,50,50);
Graphics grpx(dc);
Image* image = new Image(L"SomePhoto.png");
grpx.DrawImage(Img,rect);
delete image;
// shut down - only once per process
GdiplusShutdown(gdiplusToken);
return;
}
Your choices are: GDI+, WIC(Windows Imaging Component) or libpng
You can use GDI+. See Loading and Displaying Bitmaps.
The below code worked for me. It's free of MFC and can be used straight away to draw PNG images in a window.
Gdiplus::Image image(L"C:\\Logo.png") ;
Gdiplus::Graphics* graphics = Gdiplus::Graphics::FromHDC(GetDC(hWnd));
RectF ImgRect(0,0,y3/10,y3/10) ;
Gdiplus::Status result = graphics->DrawImage(&image, ImgRect);
Thanks for all your support and quick response to solve my problem.
If you know PNG'coding,you can decoding it. So you can draw PNG in any way~