I would like to create a program that can identify arrows in a video feed and determine the direction they are pointing at (left or right). My aim is to use this program with an arduino robot in order to determine the direction in which the bot should move.
my problem is which method to use. I ve narrowed my options down to template matching or SURF. template matching is good because it is rotation independent, therefore it can determine between left and right arrows. However since the bot will be moving, the size of the template arrow might not be equal to that of the video feed, resulting in no matches.
SURF solves this problem however it is rotation invariant. This means that Left arrows and right arrows will be considered as the same thing.
Can anyone please suggest an approach I can use for this program.
Thanks in advance for any help
P.S I will be using OpenCV for implementation.
I managed to solve the problem by using canny edge detection and HoughLinesP. The system works pretty well but has a limited rotation range at which it will detect the direction correctly (approx 15 degrees).
basically I first performed colour detection to detect the arrow, then used houghlinesp to find its outline. Out of these lines, I eliminated all those which are horizontal or vertical, leaving just the ones at the tip as shown in red. I then used the end points of each line to determine the direction.
Related
We have this camera array arranged in an arc around a person (red dot). Think The Matrix - each camera fires at the same time and then we create an animated gif from the output. The problem is that it is near impossible to align the cameras exactly and so I am looking for a way in OpenCV to align the images better and make it smoother.
Looking for general steps. I'm unsure of the order I would do it. If I start with image 1 and match 2 to it, then 2 is further from three than it was at the start. And so matching 3 to 2 would be more change... and the error would propagate. I have seen similar alignments done though. Any help much appreciated.
Here's a thought. How about performing a quick and very simple "calibration" of the imaging system by using a single reference point?
The best thing about this is you can try it out pretty quickly and even if results are too bad for you, they can give you some more insight into the problem. But the bad thing is it may just not be good enough because it's hard to think of anything "less advanced" than this. Here's the description:
Remove the object from the scene
Place a small object (let's call it a "dot") to position that rougly corresponds to center of mass of object you are about to record (the center of area denoted by red circle).
Record a single image with each camera
Use some simple algorithm to find the position of the dot on every image
Compute distances from dot positions to image centers on every image
Shift images by (-x, -y), where (x, y) is the above mentioned distance; after that, the dot should be located in the center of every image.
When recording an actual object, use these precomputed distances to shift all images. After you translate the images, they will be roughly aligned. But since you are shooting an object that is three-dimensional and has considerable size, I am not sure whether the alignment will be very convincing ... I wonder what results you'd get, actually.
If I understand the application correctly, you should be able to obtain the relative pose of each camera in your array using homographies:
https://docs.opencv.org/3.4.0/d9/dab/tutorial_homography.html
From here, the next step would be to correct for alignment issues by estimating the transform between each camera's actual position and their 'ideal' position in the array. These ideal positions could be computed relative to a single camera, or relative to the focus point of the array (which may help simplify calculation). For each image, applying this corrective transform will result in an image that 'looks like' it was taken from the 'ideal' position.
Note that you may need to estimate relative camera pose in 3-4 array 'sections', as it looks like you have a full 180deg array (e.g. estimate homographies for 4-5 cameras at a time). As long as you have some overlap between sections it should work out.
Most of my experience with this sort of thing comes from using MATLAB's stereo camera calibrator app and related functions. Their help page gives a good overview of how to get started estimating camera pose. OpenCV has similar functionality.
https://www.mathworks.com/help/vision/ug/stereo-camera-calibrator-app.html
The cited paper by Zhang gives a great description of the mathematics of pose estimation from correspondence, if you're interested.
I'm new to image processing and hope someone can help/guide me in the right direction.
So I have a picture in black/white and I want to find the corner coordinates of the inner black part of the preprocessed picture. My question is what kind of method/s will yield the most accurate result?
I want something like this (red dots shows the inner corners)
go with cv::goodFeaturesToTrack() and play with params until you get your result.
you can refer to this on why choose this and not cornerHarris: goodFeaturesToTrack vs cornerHarris
and also to this SO answer for an example: opencv-using-cvgoodfeaturestotrack-with-c-mat-variable
of course I assume you are using C++, if you are using python it won't change much...
have luck and try to do a search before asking next time
I don't know what language you're using which makes it harder to answer this question but the way I did it my last time was by applying openCV's canny edge detection algorithm. This allows you to see the edges on the image. Next find the contours. With those two functions and a little help from your friend Google, you will be able to figure this out. Good luck!
One of the aproaches would be to use just sobel independently in X and Y (in original image). Since you have binary already just find inner edge, which will be easy.
Those edges can be then sampled - take a few points of the edge. And with the help of OpenCV library function cv::fitLine find the line of the edge. Do the same with all the inner edges and compute the intersections. This approach should be fairly accurate since from the fitLine function on you basically compute the corners in sub-pixel accuracy.
I want to detect a human hand and determin its width. Is there a way to it in openCV, or any technique to do that.
I've tried searching google but couldn't find any solution.
My segmentation result:
As your question is too broad to be answered without writing a 10 page essay I'll give you a few ideas at least.
Option 1:
Detect the finger tips and fit a hand model (there should be plenty of papers, open source code and other resources available online that do hand and gesture detection). you can then position your line using that hand model.
Option 2:
The dimension you are looking for should be the shortest cross section of any hand. Place a scan line over your hand, rotate it around it's centroid and measure the distance between the transition hand - background on both ends. Then pick the minimum. Make sure you have the right rotation center. Maybe cut the fingers of using morphological operations to move the centroid a bit further down so you don't get a wrong measurement.
Option 3: Estimate the width of the hand by its total size. Human proportions usually follow some rules. See if you can find some correlation between that measure and other hand features. If you don't need too exact measures (your image resoltion suggests this) this should be the quickest and easiest solution.
There are many other options. Take a ruler and your hand and start thinking. Or do more research on gesture recognition in general. I'm sure you can apply may things they use to get your width.
I'm looking for help in solving my problem. I have a static camera, which is focus on one place. I download current view at every 1 second.
I would like to write a program which detects when someone moves the camera in a different direction. After that I would like to generate image with the shift. I am currently come up with this solution:
Create a base frame, to which I compare all future frames.
Generate edge with Canny Edge algorithm.
Then I generate the corner points with Harris algorithm.
Then I want to compare the current frame with a base frame (picture, where are just corner points on black background) with calcOpticalFlowPyrLK (Lucas-Kanade method).
Unfortunately I have problems, because depending on the lighting, the number of people, etc., the edges and corners are change. Because of this I don't know if there was a shift or not.
Can somebody give me some advices any solution how to detect shift?
Thanks for your help :)
See the opencv's standard example:
opencv/samples/cpp/phase_corr.cpp
I think it is that you are looking for.
did somebody tried to find a pizzamarker like this one with "only" OpenCV so far?
I was trying to detect this one but couldn't get good results so far. I do not know where this marker is in picture (no ROI is possible), the marker will be somewhere in the room (different ligthning effects) and not faceing orthoonal towards us. What I want - the corners and later the orientation of this marker extracted with the corners but first of all only the 5Corners. (up, down, left, right, center)
I was trying so far: threshold, noiseclearing, find contours but nothing realy helped for a good result. Chessboards or square markers are normaly found because of their (parallel) lines- i guess this can't help me here...
What is an easy way to find those markers?
How would you start?
Use other colorformat like HSV?
A step-by-step idea or tutorial would be realy helpfull. Cause i couldn't find tuts at the net. Maybe this marker isn't called pizzamarker -> does somebody knows the real name?
thx for help
First - thank you for all of your help.
It seems that several methods are usefull. Some more or less time expansive.
For me it was the easiest with a template matching but not with the same marker.
I used only a small part of it...
this can be found 5 times(4 times negative and one positive) in this new marker:
now I use only the 4 most negatives Points and the most positive and got my 5 points that I finaly wanted. To make this more sure, I check if they are close to each other and will do a cornerSubPix().
If you need something which can operate in real-time I'd go down the edge detection route and look for intersecting lines like these guys did. Seems fast and robust to lighting changes.
Read up on the Hough Line Transform in openCV to get started.
Addendum:
Black to White is the strongest edge you can have. If you create a gradient image and use the strongest edges found in the scene (via histogram or other) you will be able to limit the detection to only the black/white edges. Look for intersections. This should give you a small number of center points to apply Hough ellipse detection (or alternate) to. You could rotate in a template as a further check if you wish.
BTW.. OpenCV has Edge Detection, Hough transform and FitEllipse if you do go down this route.
actually this 'pizza' pattern is one of the building blocks of the haar featured used in the
Viola–Jones object detection framework.
So what I would do is compute the summed area table, or integral image using cv::integral(img) and then run exhaustive search for this pattern, on various scales (size dependant).
In each window you are using only 9 points (top-left, top-center, ..., bottom left).
You can train and use cvHaarDetectObjects to detect the marker using VJ.
Probably not the fastest method but it should work.
You can find more info on object detection methods using OpenCV here: http://opencv.willowgarage.com/documentation/object_detection.html