i'm newbie with opencv. Just managed to install and set it up to Visual 2013. I tested it with a sample of live stream for my laptop's camera and it works. Now i want to calculate the distance with the webcam to a red laser spot that will be in the middle of the screen(live_stream). Tell me from where can i start? I know that i must find the R(red) pixel from the middle of the screen but i dont know how to do that and what functions can i use. Some help, please?
The live stream from webcam that works is shown below:
#include "opencv2/highgui/highgui.hpp"
#include <opencv2/objdetect/objdetect.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
#include <vector>
#include <stdio.h>
int main()
{
//Data Structure to store cam.
CvCapture* cap=cvCreateCameraCapture(0);
//Image variable to store frame
IplImage* frame;
//Window to show livefeed
cvNamedWindow("Imagine Live",CV_WINDOW_AUTOSIZE);
while(1)
{
//Load the next frame
frame=cvQueryFrame(cap);
//If frame is not loaded break from the loop
if(!frame)
printf("\nno");;
//Show the present frame
cvShowImage("Imagine Live",frame);
//Escape Sequence
char c=cvWaitKey(33);
//If the key pressed by user is Esc(ASCII is 27) then break out of the loop
if(c==27)
break;
}
//CleanUp
cvReleaseCapture(&cap);
cvDestroyAllWindows();
}
Your red dot is most likely going to show up as total white in the camera stream, so I would suggest
Convert to grayscale using cvtColor().
Threshold using threshold(), for parameters use something like thresh=253, maxval=255 and mode THRESH_BINARY. That should give you an image that is all black with a small white dot where your laser is.
Then you can use findContours() to locate your dot in the image. Get the boundingRect() of a contour and then you can calculate its center to get the precise coordinates of your dot.
Also as has been already mentioned, do not use the deprecated C API, use the C++ API instead.
Related
I am trying to create a program that will open my camera, take a frame, and locate a laser point. I want to analyse each frame and find a red laser dot. Ideally, I would be able to insert a line at the x and y coordinate at the centroid of the laser dot that updates with each new frame. The camera I am using to take pictures of the laser is fairly high quality and takes pictures of size 2048x2048 so going through each pixel takes way too long. I need this software to run fairly quickly. I already have the code to open the camera and acquire frames.
laser image
What is the best way to write the code to locate the central point of the laser point within each frame?
Thanks,
#include <stdio.h>
#include <iostream>
#include "xiApiPlusOcv.hpp"
#include "opencv2/opencv.hpp"
using namespace cv;
using namespace std;
int main(int argc, char* argv[])
{
try
{
xiAPIplusCameraOcv cam;
// Retrieving a handle to the camera device
printf("Opening first camera...\n");
cam.OpenFirst();
cam.SetExposureTime(10000); //10000 us = 10 ms
// Note: The default parameters of each camera might be different in different API versions
cam.SetImageDataFormat(XI_RGB24);
printf("Starting acquisition...\n");
cam.StartAcquisition();
printf("First pixel value \n");
#define EXPECTED_IMAGES 200
for (int images = 0; images < EXPECTED_IMAGES; images++)
{
Mat cv_mat_image = cam.GetNextImageOcvMat();
cvWaitKey(20);
Mat outImg;
cv::resize(cv_mat_image, outImg, cv::Size(), .35, .35);;
imshow("image", outImg);
}
cam.StopAcquisition();
cam.Close();
printf("Done\n");
cvWaitKey(500);
}
catch (xiAPIplus_Exception& exp) {
printf("Error:\n");
exp.PrintError();
cvWaitKey(2000);
}
return 0;
}
I'm new to OpenCV and am working on a video analysis project. Basically, I want to split my webcam into two sides (left and right), and have already figured out how to do this. However, I also want to analyze each side for red and green colors, and print out the amount of pixels that are red/green. I must have gone through every possible blog to figure this out, but alas it still doesn't work. The following code runs, however instead of detecting red as the code might suggest it seems to pick up white (all light sources and white walls). I have spent hours combing through the code but still cannot find the solution. Please help! Also note that this is being run on OSX 10.8, via Xcode. Thanks!
#include <iostream>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/core/core.hpp"
using namespace cv;
using namespace std;
int main( int argc, char** argv )
{
VideoCapture cap(0); //capture the video from webcam
if ( !cap.isOpened() ) // if not success, exit program
{
cout << "Cannot open the web cam" << endl;
return -1;
}
namedWindow("HSVLeftRed", CV_WINDOW_AUTOSIZE);
namedWindow("HSVLeftGreen", CV_WINDOW_AUTOSIZE);
while (true) {
Mat image;
cap.read(image);
Mat HSV;
Mat threshold;
//Left Cropping
Mat leftimg = image(Rect(0, 0, 640, 720));
//Left Red Detection
cvtColor(leftimg,HSV,CV_BGR2HSV);
inRange(HSV,Scalar(0,0,150),Scalar(0,0,255),threshold);
imshow("HSVLeftRed",threshold);
//Left Green Detection
cvtColor(leftimg,HSV,CV_BGR2HSV);
inRange(HSV,Scalar(still need to find proper min values),Scalar(still need to find proper max values),threshold);
imshow("HSVLeftGreen",threshold);
}
return 0;
}
You're cropping a 640x720 area, which might not fit exactly your contents. Tip: Check your actual capture resolution with capture.get(CAP_PROP_FRAME_WIDTH) and capture.get(CAP_PROP_FRAME_HEIGHT). You might want to consider Mat threshold --> Mat thresholded. This is just some ranting :)
What I suspect is the actual issue is the threshold you use for HSV. According to cvtolor, section on RGB to HSV conversion,
On output 0 <= V <= 1.
so you should use a float representing your V threshold, i.e. 150 -> 150/255 ~= 0.58 etc.
I am using opencv and c++. I am doing a very simple program. What is does is it takes 3 images in a vector mat,convert those images to hsv and again stores the hsv's of the original image in a vector. I want to display all the 3 hsv images obtained. But when my program loops, it displays only the last hsv image in the vector. Here is my code: http://pastebin.com/z7FBrtxs.
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/core.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main(){
vector<Mat> imgs;
Mat left=imread("left.jpg");
Mat front=imread("front.jpg");
Mat right=imread("right.jpg");
imgs.push_back(left);
imgs.push_back(front);
imgs.push_back(right);
vector<Mat> hsvs;
Mat left_hsv;
Mat front_hsv;
Mat right_hsv;
cvtColor(left,left_hsv,CV_BGR2HSV);
cvtColor(front,front_hsv,CV_BGR2HSV);
cvtColor(right,right_hsv,CV_BGR2HSV);
hsvs.push_back(left_hsv);
hsvs.push_back(front_hsv);
hsvs.push_back(right_hsv);
for(int i=0;i<3;i++){
imshow("hsv",hsvs[i]);
}
waitKey(0);
return 0;
}
This
for(int i=0;i<3;i++){
imshow("hsv",hsvs[i]);
}
waitKey(0);
means that you are displaying all images in the window named "hsv". And after displaying the last one, you wait for user input. Thus, the images are actually all showed in the window, in sequence, it's just that they switch so fast you never see it.
Change it to
for(int i=0;i<3;i++){
imshow("hsv",hsvs[i]);
waitKey(0);
}
and you should be good.
This change means each image will be shown in the "hsv" window, and then wait for you to push a button before showing the next image.
You could also show multiple windows at once by just renaming the windows to "hsv1", "hsv2", etc.
Either use:
for(int i=0;i<3;i++){
imshow("hsv",hsvs[i]);
waitKey(0); //Note: wait for user input for every image
}
or show them in three different named windows (see documentation).
As there are no coordinates provided, I guess all images are drawn in the same default place (a viewport origin), and the last image was painted over all previous ones.
Good day everyone! So currently I'm working on a project with video processing, so I decided to give a try to OpenCV. As I'm new to it, I decided to find few sample codes and test them out. First one, is C OpenCV and looks like this:
#include <opencv/cv.h>
#include <opencv/highgui.h>
#include <stdio.h>
int main( void ) {
CvCapture* capture = 0;
IplImage *frame = 0;
if (!(capture = cvCaptureFromCAM(0)))
printf("Cannot initialize camera\n");
cvNamedWindow("Capture", CV_WINDOW_AUTOSIZE);
while (1) {
frame = cvQueryFrame(capture);
if (!frame)
break;
IplImage *temp = cvCreateImage(cvSize(frame->width/2, frame->height/2), frame->depth, frame->nChannels); // A new Image half size
cvResize(frame, temp, CV_INTER_CUBIC); // Resize
cvSaveImage("test.jpg", temp, 0); // Save this image
cvShowImage("Capture", frame); // Display the frame
cvReleaseImage(&temp);
if (cvWaitKey(5000) == 27) // Escape key and wait, 5 sec per capture
break;
}
cvReleaseImage(&frame);
cvReleaseCapture(&capture);
return 0;
}
So, this one works perfectly well and stores image to hard drive nicely. But problems begin with next sample, which uses C++ OpenCV:
#include "opencv2/opencv.hpp"
#include <string>
using namespace cv;
int main(int, char**)
{
VideoCapture cap(0); // open the default camera
if(!cap.isOpened()) // check if we succeeded
return -1;
Mat edges;
//namedWindow("edges",1);
for(;;)
{
Mat frame;
cap >> frame; // get a new frame from camera
cvtColor(frame, edges, CV_RGB2XYZ);
imshow("edges", edges);
//imshow("edges2", frame);
//imwrite("test1.jpg", frame);
if(waitKey(1000) >= 0) break;
}
// the camera will be deinitialized automatically in VideoCapture destructor
return 0;
}
So, yeah, generally, in terms of showing video (image frames) there is practically no changes, but when it comes to using im** functions, some problems arise.
Using cvSaveImage() works out nicely, but the moment I try to use imwrite(), unhandled exception arises in regards of 'access violation reading location'. Same goes for imread(), when I'm trying to load image.
So, the thing I wanted to ask, is it possible to use most of the functionality with C OpenCV? Or is it necessary to use C++ OpenCV. If yes, is there any solution for the problem I described earlier.
Also as stated here, images initially are in BGR-format, so conversion needed. But doing BGR2XYZ conversion seems to invert colors, while RGB2XYZ preserve them. Examples:
images
Or is it necessary to use C++ OpenCV?
No, there is no necessity whatsoever. You can use any interface you like and you think you are good with it (OpenCV offers C, C++, Python interfaces).
For your problem about imwrite() and imread() :
For color images the order channel is normally Blue, Green, Red , this
is what imshow() , imread() and imwrite() expect
Quoted from there
I am using OpenCV and trying to apply a Gaussian Blur to an incoming video stream. I basically use cvQueryFrame to remove a frame, blur it and display the frame onto the screen. The thing is though, my video gets stuck on the first frame after I apply the blur....anyone know why? its basically showing one frame instead of a video. The second I remove the blur it starts outputting video again.
#include "cv.h"
#include "highgui.h"
#include "cvaux.h"
#include <iostream>
using namespace std;
int main()
{
//declare initial data
IplImage *grabCapture= 0; //used for inital video frame capture
IplImage *process =0; //used for processing
IplImage *output=0; //displays final output
CvCapture* vidStream= cvCaptureFromCAM(0);
cvNamedWindow ("Output", CV_WINDOW_AUTOSIZE);
int createimage=1;
while (1)
{
grabCapture= cvQueryFrame (vidStream);
if (createimage==1)
{
process= cvCreateImage (cvGetSize(grabCapture), IPL_DEPTH_16U, 3);
createimage=0;
}
*process=*grabCapture;
cvSmooth (process,process,CV_GAUSSIAN,7,7); //line that makes it display frame instead of video
cvShowImage("Output",process);
}
//clean up data
cvReleaseImage (&grabCapture);
cvReleaseImage (&process);
cvReleaseImage (&output);
cvReleaseCapture (&vidStream);
return 0;
}
You are missing a call to cvWaitKey. This is the only way to tell OpenCV to process events and thus prevent the GUI from freezing.
Try adding this line:
cvWaitKey(10);
after cvShowImage("Output",process);.
Edit: here is the documentation for cvWaitKey