Figure out if points lays in area - opencv

Given and image and 4 corner points of an area inside the image, I want to figure out if a point p (x,y) lays inside the given area. The area is not necessarily in form of a rectangle, as the area is the result of a perspective projection of some other image.
For example:
Here I want to figure out if the pink point actually lays within the shape inside the image. In this case it does.
I was thinking about drawing an contour with drawContours and then using pointPolygonTest but I was wondering if there is an easier and more tailored way of doing it.

Related

UIBezierPath combine shapes

This is not asking the same question as How can I combine UIBezierPath drawings? even though the name is similar
I have a shape that needs to be able to scale vertically and on one side of it are rounded corners and the other side is some other path. I have drawn the following image to show what I am talking about, but this is not the exact shape I am making, but conceptually it is the same idea.
In this image, the left side is half of a rounded rectangle and the right side is half of a circle.
So I am wanting to take and essentially cut a rounded rectangle in half and basically "merge" it with another path. How can I do this?
I guess one way would be to have two layers: the top layer contains the shape on the right and the bottom layer contains the rounded rectangle, and the top layer occludes half of the rectangle. But I was hoping to not have to use two different layers, and instead be able to put all of this in one layer, so I was wondering if it was possible to merge the shapes like I mentioned.

Curved Shape Background Header in Flutter

I have a list view with "Hero" icons on the left. When I click a list item, it loads the next screen with the article text and the Hero image (which animates nicely/automatically to the correct spot on the 2nd screen).
I would have thought that was the "tough" part, but I'm now trying to get a curved shape as the top background of the 2nd screen. I would love to make it a drawn vector shape, as opposed to a bitmap and even have it drip/bounce onto the page, but at the moment...
I'm just trying to figure out how to:
draw a vector shape
have it as the background of a screen with other widgets on top (see purple curve on 2nd screen below)
I made a full sample for your curved shape in a gist here
I used CustomPainter to draw on a canvas then, with some geometric calculations, I achieved the curved shape.
Final result
How I draw it?
Before coding and on a Whiteboard I determined somethings:
My Canvas Area:
The canvas dimensions I need to draw that shape (which equals to Flutter widget's dimensions).
How and where my brush will move?
how means: what are the APIs I need to draw that shape on the canvas using the Path class.
e.g. lineTo() for a straight line, quadraticBezierTo() for a curve.
where means: Where are the points (coordinates) I need to draw the whole shape. (see yellow and green dots in the image above)
Points (coordinates) Calculations:
I used some geometric equations to calculate the coordinates. e.g. Point on a circle’s circumference
All of my calculations depend on the canvas size, that gives me a responsive shape.
Full sample here!

Opencv: How to Fit an Image into Non-Rectangular Contour?

I want to fit an image of a clown like face into a contour of another face (a person).
I am detecting the persons face and getting a elliptical-like contour.
I can figure out the center, radius, highest, lowest, left-most and right-most points.
How do I fit the clown face (a square image which I can make elliptical by cutting the face out of the empty background of a png and then detecting the contour) into the persons face?
Or at the least, how do I fit a polygon into another polygon.
I can fit a rectangular image into a rectangular contour with ease, but faces aren't that shape.
Python preferable, but C++ is also manageable, thank you.
Edit: Visual representation as requested:
I have
and I want to make it like this:
but I want the clown face to stretch over the guys face and fit within the blue contour.
I think the keyword you are looking for is Active Appearance Models. First, you need to fit a model to first face (such as this one), which lays inside the contour. Then, you should fit the same model to the clown face. After that, since you have fitted same model to both faces, you can stretch it as you need.
I haven't use AAM myself and I'm not an expert about it, so my explanation might not be enough or might not be exactly correct, but I'm sure it will give you some insight.
A simple and good answer to this question is to find the extreme top, bottom, left, and right points on your contour (head) and then resize your mask to match the aspect ration and place it to cover the 4 points.
Because human heads are elliptical you can use fitEllipse() to give you those 4 points. This will automagically fix any problems with the person tilting their head because regardless of the angle you will know which point is top, bottom, left, and right.
The relevant code for finding the ellipse is:
vector<Point> contour;
// Do whatever you are doing to populate this vector
RotatedRect ellipse = fitEllipse(Mat(contour));
There is also an example as well as documentation for RotatedRect.
// Resize your mask with these sizes for optimum fit
ellipse.size.width
ellipse.size.height
You can rotate your image like this.
UPDATE:
You may also want to find the contour's extreme points to know how much you need to scale your image to ensure that all of the face is covered.

rotated crop in opencv

I am trying to crop a picture on right on along the contour. The object is detected using surf features and than i want to crop the image of extactly as detected.
When using crop some outside boundaries of other object is includes. I want to crop along the green line below. OpenCV has RotatedRect but i am unsure if its good for cropping.
Is there way to perfectly crop along the green line
I assume you get you get your example from http://docs.opencv.org/doc/tutorials/features2d/feature_homography/feature_homography.html, so what you can do is to find the minimum axis aligned bounding box around the green bounding box, crop it from the image, use the inverted homography (H.inv()) matrix to transform that sub image into a new image (call cv::warpPerspective), and then crop your green bounding box (it should be axis aligned in your new image).
You can get the equations of the lines from the end points for each. Use these equations to check whether any given pixel lies within the green box or not i.e. does it lie between the left and right lines and between the top and bottom lines. Run this over the entire image and reset anything that doesn't lie within the box to black.
Not sure about in-built functionality to do this, but this simple methodology is guaranteed to work. For higher accuracy, you may want to consider sub-pixel checks.

Stretch an image to fit in any quadrangle

The application PhotoFiltre has an option to stretch part of an image. You select a rectangular shape and you can then grab and move the vertexes somewhere else to make any quadrangle. The image part which you selected will stretch along. Hopefully these images make my point a little clearer:
Is there a general algorithm which can handle this? I would like to obtain the same effect on HTML5 canvas - given an image and the resulting corner points, I would like to be able to draw the stretched image in such a way that it fills the new quadrangle neatly.
A while ago I asked something similar, where the solution was to divide the image up in triangles and stretch each triangle so that each three points correspond to the three points on the original image. This technique turned out to be rather exprensive and I would like if there is a more general method of accomplishing this.
I would like to use this in a 3D renderer, but I would like to work with a (2D) quadrangle.
I don't know whether PhotoFiltre internally also uses triangles, or whether it uses another (cheaper) algorithm to stretch an image like this.
Does someone perhaps know if there is a cheaper or more general method/algorithm to stretch a rectangular image, so that it fills a quadrangle given four points?
The normal method is to start with the destination, pick an appropriate grid size and then for each point in the new shape calculate the corresponding point in the source image (possibly with interpolation depending on the quality you need)
Affine transform.
Given four points for the "stretched" figure and four points for the figure it should match (e.g. a rectangle), an affine transform provides the spatial mapping you need. For each point (x1,y1) in the original image there is a corresponding point (x2,y2) in the second, "stretched" image.
For each integer-valued pixel (x2, y2) in the stretched image, use the affine transform to find the corresponding real-valued point (x1, y1) in the original image and apply its color to (x2,y2).
http://demonstrations.wolfram.com/AffineTransform/
You'll find sample code for Java and other languages online. .NET has the Matrix class.

Resources