I want to resize an image to a specific size, it gets resized but cropped as well. What am I doing wrong?
my code:
cv::Mat Processor::process_image(cv::Mat& message)
{
float scale_down = 0.5;
cv::Mat resized_message;
cv::resize(message, resized_message, cv::Size(), scale_down, scale_down);
return resized_message;
}
int main()
{
cv::namedWindow("view", cv::WINDOW_AUTOSIZE);
...
resized_image = process_image(image);
cv::imshow("view", resized_image);
cv::waitKey(30);
}
This one is my source image:
This is what I get:
It seems that the mono8 in my publish function produces the error.
img_publisher.publish(cv_bridge::CvImage(std_msgs::Header(), "mono8", message_to_publish.get_image()).toImageMsg());
because if I publish the image as bgr8 it works fine.
img_publisher.publish(cv_bridge::CvImage(std_msgs::Header(), "bgr8", message_to_publish.get_image()).toImageMsg());
So I need to convert the image to grayscale after resizing.
Related
I am trying to show an image. but imshow shows the image with big scales so that I can see the image's pixels(as shown in the image below)
as you see pixels are too big. and it is not nice. I expected something like this:
is there any way to resize the image's window size?
I am using Linux vscode
here is my code:
int main()
{
Mat O_image = imread("lena.jpg");
namedWindow("hamid", CV_WINDOW_KEEPRATIO);
imshow("hamid", O_image);
waitKey(0);
return 0;
}
the pointer changes when I move the mouse to the edges but I can't resize it.
You can use a cv::namedWindow with WindowFlags to control the size of the output window.
cv::Mat img;
img = cv::imread("Lena.jpg", CV_LOAD_IMAGE_GRAYSCALE);
cv::namedWindow("A image of Lena", CV_WINDOW_NORMAL); //CV_WINDOW_NORMAL to enable the user to resize the window
cv::imshow("A image of Lena", img);
I am programming in Qt environment and I have a Mat image with size 2592x2048 and I want to resize it to the size of a "label" that I have. But when I want to show the image, I have to multiply the width by 3, so the image is shown in its correct size. Is there any explanation for that?
This is my code:
//Here I get image from the a buffer and save it into a Mat image.
//img_width is 2592 and img_height is 2048
Mat image = Mat(cv::Size(img_width, img_height), CV_8UC3, (uchar*)img, Mat::AUTO_STEP);
Mat cimg;
double r; int n_width, n_height;
//Get the width of label (lbl) into which I want to show the image
n_width = ui->lbl->width();
r = (double)(n_width)/img_width;
n_height = r*(img_height);
cv::resize(image, cimg, Size(n_width*3, n_height), INTER_AREA);
Thanks.
The resize function works well, because if you save the resized image as a file is displayed correctly. Since you want to display it on QLabel, I assume you have to transform your image to QImage first and then to QPixmap. I believe the problem lies either in the step or the image format.
If we ensure the image data passed in
Mat image = Mat(cv::Size(img_width, img_height), CV_8UC3, (uchar*)img, Mat::AUTO_STEP);
are indeed an RGB image, then below code should work:
ui->lbl->setPixmap(QPixmap::fromImage(QImage(cimg.data, cimg.cols, cimg.rows, *cimg.step.p, QImage::Format_RGB888 )));
Finally, instead of using OpenCV, you could construct a QImage object using the constructor
QImage((uchar*)img, img_width, img_height, QImage::Format_RGB888)
and then use the scaledToWidth method to do the resize. (beware thought that this method returns the scaled image, and does not performs the resize operation to the image per se)
I am trying to get the difference between two images using the following code:
Mat getWithoutBackground(Mat img, Mat back)
{
_backgroundSubVal = 50;
cv::Mat diff;
cv::absdiff(img, back, diff);
cv::Mat diff1Channel;
cv::cvtColor(diff, diff1Channel, CV_BGRA2GRAY);
cv::Mat mask = diff1Channel > _backgroundSubVal;
cv::Mat data(img.size(), CV_8UC4, Scalar(255,255,255,0));
// copy masked area
img.copyTo(data, mask);
cv::imwrite(""1.png", data);
return similarRegions;
}
first is the background:
second is the actual image:
and here is the result:
and I am almost getting the correct solution but i would have liked to have a transparent background instead of black.
(I dont want to remove all of the picture's black colors)
I thought that the 4'th parameter in the Scalar should have done the trick for having a transparent background but i guess that I am missing something..
cv::Mat data(img.size(), CV_8UC4, Scalar(255,255,255,0));
any ideas what am i doing wrong?
I have been trying to use absdiff to find the motion in an image,but unfortunately it fail,i am new to OpenCV. The coding supposed to use absdiff to determine whether any motion is happening around or not, but the output is a pitch black for diff1,diff2 and motion. Meanwhile,next_mframe,current_mframe, prev_mframe shows grayscale images. While, result shows a clear and normal image. I use this as my reference http://manmade2.com/simple-home-surveillance-with-opencv-c-and-raspberry-pi/. I think the all the image memory is loaded with the same frame and compare, that explain why its a pitch black. Is there any others method i miss there? I am using RTSP to pass camera RAW image to ROS.
void imageCallback(const sensor_msgs::ImageConstPtr&msg_ptr){
CvPoint center;
int radius, posX, posY;
cv_bridge::CvImagePtr cv_image; //To parse image_raw from rstp
try
{
cv_image = cv_bridge::toCvCopy(msg_ptr, enc::BGR8);
}
catch (cv_bridge::Exception& e)
{
ROS_ERROR("cv_bridge exception: %s", e.what());
return;
}
frame = new IplImage(cv_image->image); //frame now holding raw_image
frame1 = new IplImage(cv_image->image);
frame2 = new IplImage(cv_image->image);
frame3 = new IplImage(cv_image->image);
matriximage = cvarrToMat(frame);
cvtColor(matriximage,matriximage,CV_RGB2GRAY); //grayscale
prev_mframe = cvarrToMat(frame1);
cvtColor(prev_mframe,prev_mframe,CV_RGB2GRAY); //grayscale
current_mframe = cvarrToMat(frame2);
cvtColor(current_mframe,current_mframe,CV_RGB2GRAY); //grayscale
next_mframe = cvarrToMat(frame3);
cvtColor(next_mframe,next_mframe,CV_RGB2GRAY); //grayscale
// Maximum deviation of the image, the higher the value, the more motion is allowed
int max_deviation = 20;
result=matriximage;
//rellocate image in right order
prev_mframe = current_mframe;
current_mframe = next_mframe;
next_mframe = matriximage;
//motion=difflmg(prev_mframe,current_mframe,next_mframe);
absdiff(prev_mframe,next_mframe,diff1); //Here should show black and white image
absdiff(next_mframe,current_mframe,diff2);
bitwise_and(diff1,diff2,motion);
threshold(motion,motion,35,255,CV_THRESH_BINARY);
erode(motion,motion,kernel_ero);
imshow("Motion Detection",result);
imshow("diff1",diff1); //I tried to output the image but its all black
imshow("diff2",diff2); //same here, I tried to output the image but its all black
imshow("diff1",motion);
imshow("nextframe",next_mframe);
imshow("motion",motion);
char c =cvWaitKey(3); }
I change the cv_bridge method to VideoCap, its seem to functions well, cv_bridge just cannot save the image even through i change the IplImage to Mat format. Maybe there is other ways, but as for now, i will go with this method fist.
VideoCapture cap(0);
Tracker(void)
{
//check if camera worked
if(!cap.isOpened())
{
cout<<"cannot open the Video cam"<<endl;
}
cout<<"camera is opening"<<endl;
cap>>prev_mframe;
cvtColor(prev_mframe,prev_mframe,CV_RGB2GRAY); // capture 3 frame and convert to grayscale
cap>>current_mframe;
cvtColor(current_mframe,current_mframe,CV_RGB2GRAY);
cap>>next_mframe;
cvtColor(next_mframe,next_mframe,CV_RGB2GRAY);
//rellocate image in right order
current_mframe.copyTo(prev_mframe);
next_mframe.copyTo(current_mframe);
matriximage.copyTo(next_mframe);
motion = diffImg(prev_mframe, current_mframe, next_mframe);
}
I'm trying to show LiveView image in real time. I use EDSDK 2.14 + Qt5 + opencv+mingw32 under Windows. I'm not very sophisticated in image processing so now I have the following problem. I use example from Canon EDSDK and all was ok until this part of code:
//
// Display image
//
I googled a lot of examples but all of them was written on C# or MFC or VB. Also I found advise to use libjpegTurbo for decompressing image and then showing it using opencv. I tried to use libjpegTurbo but failed to undestand what to do :(. Maybe somebody here have code example of the conversion LiveView stream to opencv Mat or QImage (because I use Qt)?
Here is what worked for me after following the SAMPLE 10 from the Canon EDSDK Reference. It's a starting point for a more robust solution.
In the downloadEvfData function, I replaced the "Display Image" part by the code bellow:
unsigned char *data = NULL;
EdsUInt32 size = 0;
EdsSize coords ;
// get image coordinates
EdsGetPropertyData(evfImage, kEdsPropsID_Evf_CoordinateSystem, 0, sizeof(coords), &coords);
// get buffer pointer and size
EdsGetPointer(stream, (EdsVoid**)&data);
EdsGetLenth(stream, &size);
//
// release stream and evfImage
//
// create mat object
Mat img(coords.height, coords.width, CV_8U, data);
image = imdecode(img, CV_LOAD_IMAGE_COLOR);
I've also changed the function signature:
EdsError downloadEvfData(EdsCameraRef camera, Mat& image)
And in the main function:
Mat image;
namedWindow("main", WINDOW_NORMAL);
startLiveView(camera);
for(;;) {
dowloadEvfData(camera, image);
imshow("main", image);
if (waitkey(10) >= 0);
break;
}
Based on the Canon EDSDKs example, you may append your EdsStreamRef 'stream' data with its correct length into a QByteArray. Then, use for example the following to parse the raw data from the QByteArray as a JPG into a new QImage:
QImage my_image = QImage::fromData(limagedata,"JPG"); Once it's in a QImage you can convert it into a OpenCV cv::Mat (see How to convert QImage to opencv Mat)
Well it depends on the format of the liveview-stream.
There must be some kind of delimiter in it and you need then to convert each image and update your QImage with it.
Check out this tutorial for more information: Canon EDSDK Tutorial in C#
QImage img = QImage::fromData(data, length, "JPG");
m_image = QImageToMat(img);
// -----------------------------------------
cv::Mat MainWindow::QImageToMat(QImage& src)
{
cv::Mat tmp(src.height(),src.width(),CV_8UC4,(uchar*)src.bits(),src.bytesPerLine());
cv::Mat result = tmp.clone();
return result;
}
// -------------------------
void MainWindow::ShowVideo()
{
namedWindow("yunhu",WINDOW_NORMAL);
while(1)
{
requestLiveViewImage();
if(m_image.data != NULL)
{
imshow("yunhu", m_image);
cvWaitKey(50);
}
}
}