How can you graph error as a shaded region? - c++

When using TGraphErrors, the error bars appear as crosses, in the absence of significant X errors and many, many data points (such as MCA with 16k bins or so) I'd like to be able to remove the single points and single error bars and graph the error as a shaded region bounding the curve from above and below.
But I'm still a rank beginner at using ROOT, and I cannot figure out how to leverage TGraphErrors to do what I want. Will I need to instead use a TMultiGraph instead (and calculate the above and below bounding curves) and if so how can I control the shading region?
Something like the below would be along the lines of what I'm looking for. Source

Take a look at the TGraphPainter documentation which gives a few examples. One way is to draw the TGRaphErrors using option 4:
A smoothed filled area is drawn through the end points of the vertical error bars.
You will probably find that to get the final plot to look as you want, you have to draw the same graph multiple times - once to get the shaded region, then again on top to get the central curve.
This blog post gives a working example. It's written in PyROOT, but can be easily adapted to C++.

Related

PCL, SACSegmentation detecting spheres

I'm trying to find spheres from a point cloud with pcl::sacSegmentation using RANSAC. The cloud is scanned with an accurate terrestial scanner from one station. The cloud density is about 1cm. The best results so far are shown in the image below. As you can see the cloud contains 2 spheres (r=7,25cm) and a steel beam where the balls are attached.. I am able to find three sphere candidates whose inlier points are extracted from cloud in the image (You can see two circle shapes on the beam near the spheres).
Input point cloud. Inlier points extracted
So, it seems that I am close. Still the found sphere centers are too much (~10cm) away from the truth. Any suggestion how could I improve this? I have been tweaking the model parameters quite some time. Here are the parameters for the aforementioned results:
seg.setOptimizeCoefficients(true);
seg.setModelType(pcl::SACMODEL_SPHERE);
seg.setMethodType(pcl::SAC_RANSAC);
seg.setMaxIterations(500000);
seg.setDistanceThreshold(0.0020);
seg.setProbability(0.99900);
seg.setRadiusLimits(0.06, 0.08);
seg.setInputCloud(cloud);
I also tried to improve the results by including point normals in the model with no better results. Yet there are couple parameters more to adjust so there might be some combinations I had not tried.
I happily give you more information if needed.
Thaks
naikh0u
After some investigation I have come in to conclusion that I can't find spheres with SACSegmentation from a cloud that contains lot of other points that don't belong in any sphere shape. Like in my case the beam is too much for the algorithm.
Thus, I have to choose the points that show some potential being a part of a sphere shape. Also I think, I need to separate the points belonging in different spheres. I tested and saw that my code works pretty well if the input cloud has only sphere points for single sphere with some "natural" noise.
Some have solved this problem by first extracting all points belonging to planes and then searched for spheres. Others have used colors of the target (in case of camera) to extract only needed points.
Deleting plane points should work for my example cloud, but my application may have more complex shapes too so it may be too simple..
..Finally, I got satisfied results by clustering the cloud with pcl::EuclideanClusterExtraction and feeding the clusters for sphere search one by one.

Detecting the locations of circles and crosses in an image

I'm new to OpenCV and was wondering if anybody could direct me to the most suitable algorithm(s) to tackle the challenge of identifying the locations of circles and crosses in images that look like the following . .
[
Sometimes there are lines connecting . .
[
They might even be hand drawn like this one . .
So far I have looked at the template matching example, but it is probably not the correct approach, and it doesn't scale the sizes of the templates to the images.
So given the following observations . . .
The crosses and circles may overlap.
If the diagram is in colour,
the colours will be identical for crosses and identical for circles.
Sometimes they will be joined by lines, sometimes not.
There may be other shape symbols in the plots
They symbols will be of similar size and shape, but might not be computer generated, so will not necessarily be identical.
Where should I begin my adventure?
Not an easy task.
For the colored case, you should start by separating the color planes. There is some chance that you can get the markers apart.
But for the b&w case, there is no escape, you must go deeper.
I would try to detect the grid lines first, for example using a Hough line detector, as accurately as possible. Then erase those lines.
Then try to find the crosses, which are short oblique line segments (most of the time broken by the previous operations).
The circles might be detected by a Hough circle detector, using a small range of radii.
Alternatively, a rige or edge detector can be used to get short segments and short curved arcs. You may have to add some filtering criteria to avoid the joining lines.
Like said, it's not a easy task.
One of possible way could be machine learning. I think of cascade classifier (aka Viola Jones method) that pretty nice for detection of object. It's pretty easy to implement with openCV but it need to understand how it works and a large amount of sample.
You can try to use couple of ideas:
1) FFT can help to remove grid. Something like this.
2) Markers (crosses and circles) are the objects with angle of gradient, that differs from right angles. It may help to localize them.

Finding Circle Edges :

Finding Circle Edges :
Here are the two sample images that i have posted.
Need to find the edges of the circle:
Does it possible to develop one generic circle algorithm,that could find all possible circles in all scenarios ?? Like below
1. Circle may in different color ( White , Black , Gray , Red)
2. Background color may be different
3. Different in its size
http://postimage.org/image/tddhvs8c5/
http://postimage.org/image/8kdxqiiyb/
Please suggest some idea to write a algorithm that should work out on above circle
Sounds like a job for the Hough circle transform:
I have not used it myself so far, but it is included in OpenCV. Among other parameters, you can give it a minimum and maximum radius.
Here are links to documentation and a tutorial.
I'd imagine your second example picture will be very hard to detect though
You could apply an edge detection transformation to both images.
Here is what I did in Paint.NET using the outline effect:
You could test edge detect too but that requires more contrast in the images.
Another thing to take into consideration is what it exactly is that you want to detect; in the first image, do you want to detect the white ring or the disc inside. In the second image; do you want to detect the all the circles (there are many tiny ones) or just the big one(s). These requirement will influence what transformation to use and how to initialize these.
After transforming the images into versions that 'highlight' the circles you'll need an algorithm to find them.
Again, there are more options than just one. Here is a paper describing an algoritm
Searching the web for image processing circle recognition gives lots of results.
I think you will have to use a couple of different feature calculations that can be used for segmentation. I the first picture the circle is recognizeable by intensity alone so that one is easy. In the second picture it is mostly the texture that differentiates the circle edge, in that case a feature image based based on some kind of texture filter will be needed, calculating the local variance for instance will result in a scalar image that can segment out the circle. If there are other features that defines the circle in other scenarios (different colors for background foreground etc) you might need other explicit filters that give a scalar difference for those cases.
When you have scalar images where the circles stand out you can use the circular Hough transform to find the circle. Either run it for different circle sizes or modify it to detect a range of sizes.
If you know that there will be only one circle and you know the kind of noise that will be present (vertical/horizontal lines etc) an alternative approach is to design a more specific algorithm e.g. filter out the noise and find center of gravity etc.
Answer to comment:
The idea is to separate the algorithm into independent stages. I do not know how the specific algorithm you have works but presumably it could take a binary or grayscale image where high values means pixel part of circle and low values pixel not part of circle, the present algorithm also needs to give some kind of confidence value on the circle it finds. This present algorithm would then represent some stage(s) at the end of the complete algorithm. You will then have to add the first stage which is to generate feature images for all kind of input you want to handle. For the two examples it should suffice with one intensity image (simply grayscale) and one image where each pixel represents the local variance. In the color case do a color transform an use the hue value perhaps? For every input feed all feature images to the later stage, use the confidence value to select the most likely candidate. If you have other unknowns that your algorithm need as input parameters (circle size etc) just iterate over the possible values and make sure your later stages returns confidence values.

Counting objects on a grid with OpenCV

I'm relatively new to OpenCV, and I'm working on a project where I need to count the number of objects on a grid. the grid is the background of the image, and there's either an object in each space or there isn't; I need to count the number present, and I don't really know where to start. I've searched here and other places, but can't seem to find what I'm looking for. I will need to be tracking the space numbers of the grid in the future, so I will also eventually need to know whether each grid space is occupied or empty. I'm not going so far as to ask for a coded example, but does anybody know of any source or tutorials to accomplish this task or one similar to it? Thanks for your help!
Further Details: images will come from a stable-mounted camera, objects are of relatively uniform shape, but varying size and color.
I would first answer a few questions:
Will an object be completely enclosed in a grid cell? Or can it be placed on top of a grid line? (In other words, will the object hide a line from the camera?)
Will more than one object be in one cell?
Can an object occupy more than one cell? (closely related to question 1)
Given reasonable answers to those questions, I believe the problem can be broken into two parts: first, identify the centers of each grid space. To count objects, you can then sample that region to see if anything "not background" is there.
You can then assume that a grid space is defined by four strong, regularly-placed, corner features. (For the sake of discussion, I'll assume you've performed the initial image preparation as needed: histogram equalization, gaussian blur for noise reduction, etc.) From there, you might try some of OpenCV's methods for finding corners (Harris corner detector, cvGoodFeaturesToTrack, etc). It's likely that you can borrow some of the techniques found in OpenCV's square finding example (samples/c/square.c). For this task, it's probably sufficient to assume that the grid center is just the centroid of each set of "adjacent" (or sufficiently near) corners.
Alternatively, you might use the Hough transform to identify the principal horizontal and vertical lines in the image. You can then determine the intersection points to identify the extents of each grid cell. This implementation might be more challenging since inferring structure (or adjacency) from "nearby" vertices in order to find a grid center seems more difficult.

Image Segmentation with boost graph

I recently discovered boost::graph.
Since I have never used Graph theory before I was wondering how i would solve the following problem with boost graph.
Lets say I've got a simple(greyscale) 2D Image and I'd like to extract Regions from it which suffice a specific criterion, e.g. pixel value > threshold.
Lets above is white, below is black.
How would I implement that?
My first clue was adding one single Vertex to the graph for every pixel in the image.
And then connect every pixel Vertex to its neighbours with the same colour(white/black).
And then I could extract regions with the connected_components() function.
Or is it more effective to connect all neighbouring pixels and encode the border information into the edge(border edge, nonborder edge)?
Actually there are some interesting graph-theory based segmentation algorithms out there, called graph-cut segmentation. They use colored edges to encode differential information between neighboring pixels.
For your very simple segmentation though using graphs at all seems overkill to me.
I would definitely do the former where you create a vertex for each pixel, and then connect pixels (or adjacent pixels depending on what you are trying to do) that share your criterion. That way you could do a "pixel-walk" to find all the areas of your image (or at least adjacent areas) that satisfy a specific criterion.
In order to find the first pixel that fits your criterion in order to start the walking sequence there are a couple methods you could use. 1) a random pick of pixels from the image, 2) save a list pointers to pixels that fit your different criteria (you only need one pixel for each criteria), or 3) save some type of gradient information on the image so that by picking just one pixel from the image, you can then search along the gradient flows to find the pixel you're looking for (i.e., the gradients would give you directional information on where you need to pick you next pixel to get closer to the desired criterion you're looking for). I would think choices 1 or 2 would be easiest to implement.
Hope this helps,
Jason