Rectangle matrix calculations in OpenCV - c

I had a generalized question to find out if it was possible or not to do matrix calculations on a rectangle. I have a CvRect that has information stored in it with coordinates and I have a cvMat that has transformational data. What I would like to know is if there was a way to get the Rect to use the matrix data to generate a rotated, skewed, and repositioned rectangle out of it. I've searched online, but I was only able to get information on image transforms.
Thanks in advance for the help.

No, this is not possible. cv::Rect is also not capable of that, as it only describes rectangles in a Manhattan world. There is cv::RotatedRect, but this also does not handle skewing.
You can, however, feed the corner points of your rectangle to cv::transform:
http://opencv.itseez.com/modules/core/doc/operations_on_arrays.html?highlight=transform#cv2.transform
You will then obtain four points that are transformed accordingly. Note that there are also more specialized versions of this function, e.g. warpPerspective() and warpAffine().

Related

Using glLoadMatrixd on specific vertices?

I am trying to do skeletal animation in legacy OpenGL and thought I could use matrices on individual vertices. When I programmed it and it didn't work, I did some Googling to find this: https://www.talisman.org/opengl-1.1/Reference/glLoadMatrix.html
GL_INVALID_OPERATION is generated if glLoadMatrix is executed between the execution of glBegin and the corresponding execution of glEnd.
So now I'm stumped. Here is a diagram:
Bones are labeled in red. I'm trying to do skeletal animation so there are two rectangles. One uses Bone 0 and the second uses Bone 1. Only specific vertices of the triangles that make the second rectangle use the rotation matrix of Bone 1, and the ones that don't use the rotation matrix of Bone 0, kind of making a snake, if that makes sense.
Since I cannot use glLoadMatrix for individual vertices in a triangle, what other way can I displace a vertex based on a stored matrix? Perhaps multiply some of the matrix values to the vertex? Not sure how to go about doing that. Any input is appreciated, thanks!
You mention the two rectangles Bone0 and Bone1. You need to draw them separately since they need to have separate transformation matrices. Two points of the two rectangles are coincident, your transformation matrix to draw Bone1 must ensure that:
glTranslateF(...);
glRotateF(...); /* position rectangle Bone0 */
glBegin(GL_QUADS); /* draw rectangle Bone0 */
glVertex3f(...); /* draw it */
...
glEnd();
glPushMatrix(); /* save transformation matrix */
glMulMatrix(...); /*
* as per your drawing, this is not just a
* simple translate/rotate operation, but
* a translate/shear
* you need to do that manually
*/
glBegin(GL_QUADS); /*
* draw rectangle Bone1. Two of the vertices are
* coincident with two of rectangle Bone0. Your
* shear matrix must ensure they are
*/
glVertex3F(...);
glEnd();
What you're trying to do is called skinning! And unfortunately it will involve a bit more effort than your approach. It is possible to do it between one begin and end, which is generally preferable.
The easiest way is not to use OpenGL to transform your vertices. Use your favourite matrix math library to multiply the vertices with your bone matrices before they get passed to OpenGL. If the number of vertices is not too large, it won't slow you down much.
The harder way is to implement a skinning shader. This book chapter provides a good introduction on how that is done. The principle is to upload multiple matrices to OpenGL, and give each vertex an index which says which matrix to multiply with. This will be much faster than the easy approach.
GPUs are fast because they are optimized for doing the same operation on a large set of data - the tradeoff for this is that you can't modify the state (such as changing the matrix) while a draw call is in progress.
Heh, have been doing a lot of math stuff since I posted my question and checked back just now to post an answer for anyone with the same question, and I noticed I already have some answers, so thanks for answering with your input!
Since I have figured out a solution, though, I thought I would post an answer along with these other two.
Basically, what I am doing with the rendering is per-vertex rendering anyway, where it reads the vertices of each triangle from a data buffer and all of that, so it wasn't too much trouble to go ahead and write a custom function to multiply a matrix to a vertex, so a copy of the vertex is loaded from the buffer, the matrix is multiplied to it based on which bone the vertex is mapped to, and then that is used for rendering that particular vertex on the triangle.
Funny that I already had implemented what #Hannesh suggested and I just had to write the multiplier function. Very cool!
The harder way is to implement a skinning shader. This book chapter provides a good introduction on how that is done. The principle is to upload multiple matrices to OpenGL, and give each vertex an index which says which matrix to multiply with. This will be much faster than the easy approach.
Thanks again! I'll up-vote whenever I have the reputation to do so!

Simple Flat Plane Tessellation Shader

Part 1:
So I want to create a basic tessellation program that takes a plane of quads and transforms it into a more, well, detailed/tessellated plane of quads. Such as the picture below. How much it gets tessellated would depend on user controls, passed in by a uniform (initially). However I am so new to tessellation shaders that I can't even figure out how to do this.
How is this typically done? Surely you shouldn't actually draw the plane of quads prior to the shader program, since from my understanding quads won't get tessellated this way, instead the get tessellated into a way like the below picture:
I believe the answer could to be to draw a plane of points, and these points are then tessellated into more points, and these points are transformed into quads of the appropriate size in the geometry shader I think? Alternatively, instead of converting points into quads could I just draw quads between each four closest points (that would be much better)? Examples very much appreciated!
NOTE: Using GLSL > 4.0 & C only (No C++/Python)
Part 2:
After I get part 1 working, how would I make it so that certain quads are more tessellated than others, such as this?:
I want the parts closer to the camera to be more tessellated.
Part 3:
If I were able to get that far, the next part would be to alter the z-axis of points to make the plane into an interesting environment. This would be done by reading in a 2Dsampler, I know how to do that and all. However, if I am correct in Part 1 about using a plane of points then I need to do more than just alter the points that are converted into quads, because quads need to be sharing vertices essentially in order there to be no gaps between quads. How would that be done? Alternatively if we draw quads between points, with each point being the appriate height, then this wouldn't be a issue.
Part 1
Yes you're correct: generate a 'patch' as a simple grid of points, specify the tesselation levels as uniforms into the TCS (tesselation control shader) and generate the vertex data in the TES (tesselation evaluation shader).
Sounds complicated? Here's a nice tutorial I based my work on: http://antongerdelan.net/opengl/tessellation.html
Part 2
What you are talking about here is LOD (or level of detail). You would need to tesselate and render the higher polygon-count bottom-left corner of your mesh as a separate object.
Your suggested approach is correct: break the overall scene into 'chunks' and determine the LOD (i.e. the tesselation parameters) for each chunk separately, usually by some distance-to-camera algorithm.
Part 3
Another excellent tutorial which does exactly what you are after I believe: http://codeflow.org/entries/2010/nov/07/opengl-4-tessellation/
I used this approach to get a very highly detailed but memory and frame efficient terrain.
Hope this helps.

Drawing largers points with X11

I know X11 has XDrawPoints for drawing multiple points in a batch, but I'd like to have slightly larger points sometimes (useful if you're eg: drawing a line through them), but can't find any way to draw larger points without doing something kludgy like drawing a tiny filled rectangle, or zero-length line with endcaps.
Is there a reasonable way to set the point size that I'm missing?
A point is a single pixel in Xlib. But XFillArcs() would let you create a list of XArc structures that describe small circles. Then you can scale these circles to any radius by setting XArc.width and XArc.height.

Blob detection in C (not with OPENCV)

I am trying to do my own blob detection who will receive a real time video, and try to detect a white paper sheet.
Even if is something written inside the paper. I need to detect the paper and is corner, because what i really want is to draw a opengl polygon over the paper in each corner of the paper will be a corner of the polygon. Then i need the coordinates of the paper to do other stuffs.
So i need to:
- detect a square white blob.
- get the coordinates of the cornes
- draw a polygon over the white sheet.
Any ideias how can i do that?
Much depends on context. For example, suppose that you:
know that the paper is always roughly centered (i.e. W/2, Y/2 is always inside the blob), and no more rotated than 45 degrees (30 would be better)
have a suitable border around the sheet so that the corners never touch the edges of the FOV
are able (through analysis of local variance, or if you're lucky, check of background color or luminance) to say whether a point is inside or outside the blob
the inside/outside function never fails (except possibly in the close vicinity of a border)
then you could walk a line from a point on the border (surely outside) and the center (surely inside), even through bisection, and find a point - an areal - on the edge.
Two edge points give a rect (two areals give a beam), two rects give an intersection (two beams give a larger areal) - and there's your corner. You should carry along the detection uncertainty (areal radius) in order to validate corners (another less elegant approach is to roughly calculate where the corner is, and pinpoint it with a spiral search or drunkard's walk).
This algorithm is amenable to parallelization and, as long as the hypotheses hold, should be really fast.
All that said, it remains a hack -- I agree with unwind, why reinvent the wheel? If you have memory or CPU constraints (embedded systems, etc.), I believe there ought to be OpenCV and e-Vision "lite" ports also for ARM and embedded platforms.
(Sorry for my terminology - I'm monkey-translating from Italian. "Areal" is likely to correspond to your "blob", a beam is the family of lines joining all couples of points in two different blobs, line intensity being the product of distance from a point from its areal's center)
I am trying to do my own blob detection who will receive a real time video, and try to detect a white paper sheet.
Your first shot could be a simple flood-fill. That is, select a good threshold to binarize the image and apply the algorithm. The threshold can be fixed if you know the paper is always brighter than X and the background is always darker than this. Or this can be an adaptive threshold, for example Otsu's method. OpenCV offers this for free.
If you'd need to speed it up you could use a union-find data structure.
Finally you'd need to come up with some heuristic how to identify the corners (e.g. the four extreme values in x/y direction).
Then i need [...] the coordinates of the cornes [...]
Then you don't need blob detection, but corner detection or contour detection in the first place. OpenCV has some nice functionality for exactly this.
If you can't use it, I would suggest to binarize the image as above and use a harris-detector to find the corners of the object.
OpenCV's TBB support could also come quite handy if you'd use it and you have problems to meet your real-time requirements.

Triangulation of polygon

Im trying to triangulate a polygon for use in a 3d model. When i try using the ear method on a polygon with points as dotted below, i get triangles where the red lines are. Since there are no other points inside these triangles this is probably correct. But i want it to triangulate the area inside the black lines only. Anyone know of any algorithms that will do this?
There are many algorithms to triangulate a polygon that do not need partitioning into monotone polygons first. One is described in my textbook Computational Geometry in C, which has code associated with it that can be freely downloaded from that link (in C or in Java).
You must first have the points in order corresponding to a boundary traversal. My code assumes counterclockwise, but of course that is easy to change. See also the Wikipedia article. Perhaps that is your problem, that you don't have the boundary points consistently organized?
The usual approach would be to split your simple polygon into monotone polygon using trapezoid decomposition and then triangulate the monotone polygons.
The first part can be achieved with a sweep line algorithm. And speed-ups are possible with the right data-structure (e.g. doubly connected edge list). The best description of this, that I know, can be found in Computational Geometry. This and this also seem helpful.
Wikipedia suggest that you break the polygon up into monotone polygons. You check that the polygon is not concave by simply checking for all angles being less than 180 degrees - any corners which has a angle of over 180 is concave, and you need to break it at that corner.
If you can use C++, you can use CGAL and in particular the example given here that can triangulate a set of non-intersected polygons. This example works only if you already know the black segments.
You need to use the EarClipping algorithm, not the Delaunay. See the following white paper: http://www.geometrictools.com/Documentation/TriangulationByEarClipping.pdf

Resources