The function of cv2.min - python-2.7

I'm new to computer vision and OpenCV, so please mind the immature language. Can someone explain me what's the function of cv2.min?
I have this code that coverts from BGR to RGV (red, green ,value) from OpenCV book:
b, g, r = cv2.split(src)
cv2.min(b, g, b)
cv2.min(b, r, b)
cv2.merge((b, g, r), dst)
where src and dst are source and destination vectors for the image.
My specific questions are:
What is cv2.min doing to b in both the iterations? How are values being assigned to b since it's being evaluated two times for both r and g ?
Please let me know what's happening in this code.

Can someone explain me what's the function of cv2.min?
Look at the doc:
Python: cv2.min(src1, src2[, dst]) → dst
The functions min calculate the per-element minimum of two arrays, or array and scalar
How are values being assigned to b since it's being evaluated two times for both r and g ?
You can break down like this:
cv2.min(b, g, b1) # b1 contains the minimum values between b and g
cv2.min(b1, r, b2) # b2 contains the minimum values between b1 and r
b = b2
What is cv2.min doing to b in both the iterations?
The i-th element of b will be the minimum element in b(i), g(i), r(i):
# Pseudocode
for each row
for each col
b(row, col) = min( b(row, col), g(row, col), r(row, col) )
However, this probably this is not correct, since the V value in HSV is computed as max(R,G,B), and the order of your channels is inverted. To get RGV color space you need to do this:
b, g, r = cv2.split(src)
cv2.max(b, g, b)
cv2.max(b, r, b)
# now 'b' contains the 'v = max(r,g,b)'
cv2.merge((r, g, b), dst)

Related

Prolog: Find all equilateral triangles which are built from DB points

I'm new to Prolog and my task requires finding all equilateral triangles which are built from DB points. As a result, I'm getting identical points of the triangles. I do not understand what the problem is. Help me pls!
:- dynamic
point/3.
%?Point_Sign, ?Abscissa, ?Ordinate
db_filling:-
point(_,_,_),!.
db_filling:-
assert(point(a,1,1)),
assert(point(b,1,2)),
assert(point(c,1,3)),
assert(point(d,2,2)),
assert(point(e,3,3)),
assert(point(f,-1,1)),
assert(point(g,-2,1)),
assert(point(h,-2,2)),
assert(point(i,-3,3)),
assert(point(j,-3,-1)),
assert(point(k,-3,-2)),
assert(point(l,-3,-3)),
assert(point(n,-1,-1)),
assert(point(m,-3,0)),
assert(point(o,3,0)),
assert(point(p,0,3)).
% +List
points_main(Xs):-
db_filling,
findall(Xs1,equilateral_triangles(Xs1),Xs).
% +Points
equilateral_triangles([P1,P2,P3]):-
point(P1,X1,Y1),
point(P2,X2,Y2),
point(P3,X3,Y3),
L1 is sqrt((X2 - X1)^2 + (Y2 - Y1)^2),
L2 is sqrt((X3 - X2)^2 + (Y3 - Y2)^2),
L3 is sqrt((X1 - X3)^2 + (Y1 - Y3)^2),
L1 = L2,
L2 = L3.
Result:
?- points_main(Res).
Res = [[a, a, a], [b, b, b], [c, c, c], [d, d, d], [e, e, e], [f, f, f], [g, g|...], [h|...], [...|...]|...].
You have a couple of fundamental issues here.
From memory, the two-dimensional coordinates of an equilateral triangle cannot all be integers. You must have at least one irrational number. Computers are not good at representing irrational numbers.
So, you're also confusing real maths with computer maths. You can't simply get the sqrt and check for equality.
To illustrate I produced these three points:
point(j1,0,0).
point(j2,1,0).
point(j3,0.5,0.866025403784439). % 1/2 & sqrt(3)/2
That's an equilateral triangle.
When I run that with your code, the lengths that get produced are like this:
[1.0,1.0000000000000004,1.0000000000000004]
They are all effectively 1.0, but of course 1.0000000000000004 is not 1.0. So, even this doesn't comeback as a equal.
So you are really forced to check the confidence as an epsilon to say two numbers are equal.
Here's what I did to do that:
points_main(Xs):-
findall(Xs1,equilateral_triangles(Xs1),Xs).
equilateral_triangles([P1,P2,P3]):-
point(P1,X1,Y1),
point(P2,X2,Y2),
P1 \= P2,
point(P3,X3,Y3),
P1 \= P3,
P2 \= P3,
L12 is sqrt((X2 - X1)^2 + (Y2 - Y1)^2),
L23 is sqrt((X3 - X2)^2 + (Y3 - Y2)^2),
L31 is sqrt((X1 - X3)^2 + (Y1 - Y3)^2),
D1223 is abs(L12 - L23),
D1223<0.00000001,
D2331 is abs(L23 - L31),
D2331<0.00000001,
D3112 is abs(L31 - L12),
D3112<0.00000001.
Now, if I run that against my points above I get this:
?- points_main(Xs).
Xs = [[j1, j2, j3], [j1, j3, j2], [j2, j1, j3], [j2, j3, j1], [j3, j1, j2], [j3, j2, j1]].
All combinations of the above three points - so, yes, they are all equilateral triangles.
If I run against your original points, as expected, there are no equilateral triangles.
A few side notes.
(1) I removed all of the assert code. It wasn't helpful nor necessary to get your code working.
(2) you could define my j3 point as point(j3,0.5,X) :- X is sqrt(3)/2. and your original maths would work. However, this is just lucky. When dealing will floating-point numbers you can never be sure that two numbers are equal even though they should be.
(3) I introduced P1 \= P2, etc, to prevent the points unifying to themselves. That's why you got [a,a,a],... etc.
The reason you get odd results is that your
...
point(P1,X1,Y1),
point(P2,X2,Y2),
point(P3,X3,Y3),
...
is producing the Cartesian Product of your set of points. If you had just 4 points defined, this would produced 43 (64) possible results.
Since you are talking triangles here, where for a given 3 points A, B, and C, whether the triangle they describe is labelled ABC, ACB, BAC, BCA, CAB, CBA is irrelevant: they all describe exactly the same triangle, so what your are looking for are combinations: a selection of items from a set where order is not important, so {a,b,c] and {c,b,a] are the same combination.
In Prolog, getting combinations is easy:
combination( [] , [] ) .
combination( [H|T] , [H|T2] ) :- combination(T,T2).
combination( [_|T] , T2 ) :- combination(T,T2).
The only caveat is that the 2nd argument to combination/2 must be seeded as a list of the desired length. To draw combinations of 3 things from a set of 5 things is as easy as:
combination( [a,b,c,d,e] , [X,Y,Z] ).
Once you have that, getting the set of points from which to draw is easy, too, using findall/3 or setof/3:
setof( p(P,X:Y) , point(P,X,Y) , Ps ) ,
The one tricky thing is that floating point arithmetic leaves much to be desired, what with floating point jitter and all. This is how I'm computing distance:
%-----------------------------------------------------------------------
% computes the distance between two points on the Cartesian plane.
% the distance, D, is returned as an integer with an implied scale of 5,
% so the distance 1.23456789 is returned as 123457 (rounded up)
% ----------------------------------------------------------------------
distance( X1:Y1 , X2:Y2 , D ) :-
V is sqrt( (X2-X1)^2 + (Y2-Y1)^2 ) ,
D is round( 100000 * V )
.
Putting it together, we get this (https://swish.swi-prolog.org/p/zHAfMTtA.pl):
equilateral_triangle( T ) :-
setof( p(P,X:Y) , point(P,X,Y) , Ps ) ,
combination(Ps,[A,B,C]),
equilateral_triangle(A,B,C,T)
.
%--------------------------------------------------------------------------------
% combination( +Set, +Combination )
%
% Takes a set (a list of distinct things) of M things and produces
% on backtracking all the combinations of M things taken N at a time.
%
% Combination, the 2nd argument MUST be initialize as a list of the desired
% length. For example, to get all the combination of 8 things taken 3 at a time,
% you'd say something like this:
%
% ?- length(C,3), combination([a,b,c,d,e],C).
%
% And get back
%
% C = [a, b, c]
% C = [a, b, d]
% C = [a, b, e]
% C = [a, c, d]
% C = [a, c, e]
% C = [a, d, e]
% C = [b, c, d]
% C = [b, c, e]
% C = [b, d, e]
% C = [c, d, e]
%
%--------------------------------------------------------------------------------
combination( [] , [] ) .
combination( [H|T] , [H|T2] ) :- combination(T,T2).
combination( [_|T] , T2 ) :- combination(T,T2).
%--------------------------------------------------------------
% 3 points comprise an equilateral triangle if the triangle
% that they describe has legs of equal length
%--------------------------------------------------------------
equilateral_triangle( p(A,Pa), p(B,Pb), p(C,Pc) , t(A,B,C) ) :-
distance(Pa,Pb,D),
distance(Pb,Pc,D),
distance(Pc,Pa,D).
%-----------------------------------------------------------------------
% computes the distance between two points on the Cartesian plane.
% the distance, D, is returned as an integer with an implied scale of 5,
% so the distance 1.23456789 is returned as 123457 (rounded up)
% ----------------------------------------------------------------------
distance( X1:Y1 , X2:Y2 , D ) :-
V is sqrt( (X2-X1)^2 + (Y2-Y1)^2 ) ,
D is round( 100000 * V )
.
point( a , 0 , 0 ) .
point( b , 5 , 0 ) .
point( c , 2.5 , 4.33012701892 ) .
point( d , 1 , 1 ) .
point( e , 6 , 1 ) .
point( f , 3.5 , 5.33012701892 ) .

Is OpenVX warpAffine accept a transposed matrix and how does it defined as row major?

I am new to OpenVX, learning from the document that OpenVX uses a row-major storage. And the below matrix access example illustrate it, just like the ordinary row-major access pattern as we used in plain C code.
Then I go to the vx_matrix and vxCreateMatrix document page. The former has such statements:
VX_MATRIX_ROWS - The M dimension of the matrix [REQ-1131]. Read-only [REQ-1132]. Use a vx_size parameter.
VX_MATRIX_COLUMNS - The N dimension of the matrix [REQ-1133]. Read-only [REQ-1134]. Use a vx_size parameter.
While the latter said:
vx_matrix vxCreateMatrix(
vx_context c,
vx_enum data_type,
vx_size columns,
vx_size rows);
So according to my comprehension, in OpenVX world, when i said an MxN matrix, M refers to the row size and N refers to the column size. And the vxCreateMatrix declaration just follow what the row-major storage said, parameter column first and then row.
However, it really confuses me when i reach Warp Affine page, it said:
This kernel performs an affine transform with a 2x3 Matrix M with this method of pixel coordinate translation [REQ-0498]:
And the C declartion:
// x0 = a x + b y + c;
// y0 = d x + e y + f;
vx_float32 mat[3][2] = {
{a, d}, // 'x' coefficients
{b, e}, // 'y' coefficients
{c, f}, // 'offsets'
};
vx_matrix matrix = vxCreateMatrix(context, VX_TYPE_FLOAT32, 2, 3);
vxCopyMatrix(matrix, mat, VX_WRITE_ONLY, VX_MEMORY_TYPE_HOST);
If the M is a 2x3 matrix, according to the previous section, it should has 2 row and 3 column. Then why should it be declared as mat[3][2] and createMatrix accept column=2 and row=3 as argument? Is my comprehension totally wrong?
This would be a good start and help for your implementation
https://software.intel.com/content/www/us/en/develop/documentation/sample-color-copy/top/color-copy-pipeline/color-copy-pipeline-the-scan-pre-process-openvx-graph.html

Plane Equation From 3 Points Not Returning Correct Values

As part of a raytracer experiment I'm working on in my high school classes, I need to make it so that I can get the 4 parts of a plane equation from 3 different points. By 4 parts i mean in the equation Ax + By + Cz = D I need to find A, B, C, and D. I understand the math behind this as its relatively simple vector math, but my code doesn't seem to work.
The function I use to construct the Plane object from the 3 points is as follows:
Plane::Plane(Vec3 A, Vec3 B, Vec3 C)
{
//Getting both vectors
Vec3 AB = B - A;
Vec3 AC = C - A;
//Cross Product
Vec3 cr = AB.cross(AC);
a = cr.getX();
b = cr.getY();
c = cr.getZ();
d = a * A.getX() + b * B.getY() + c * C.getZ();
}
In this, Vec3 is just a vector class that holds (x, y, z), and the function names are pretty self explanatory (I hope).
An example of what it outputs:
If I put the vectors (-3, 0, 1), (2, 3, 0), and (0, 2, 3) into this, I get the following results
A = 8
B = -13
C = 1
D = -60
A, B, and C in this are correct, but D is not.
I'm not entirely certain what's wrong with the code, since it will sometimes get the output correctly on certain vectors, sometimes get parts correct, or sometimes get nothing correct at all, which leads me to believe there's a math mistake. Any help is appreciated.
Since in your example, you get the values for A, B, and C correct, the first place to look is in the calculation of D.
In your calculation of d, you use parts of three different vectors. This is not what the equation for D says to do. You want to use the three parts from one vector.
d = a * A.getX() + b * A.getY() + c * A.getZ();
This should work for any of the three vectors.

Numpy - row-wise outer product of two matrices

I have two numpy arrays: A of shape (b, i) and B of shape (b, o). I would like to compute an array R of shape (b, i, o) where every line l of R contains the outer product of the row l of A and the row l of B. So far what i have is:
import numpy as np
A = np.ones((10, 2))
B = np.ones((10, 6))
R = np.asarray([np.outer(a, b) for a, b in zip(A, B)])
assert R.shape == (10, 2, 6)
I think this method is too slow, because of the zip and the final transformation into a numpy array.
Is there a more efficient way to do it ?
That is possible with numpy.matmul, which can do multiplication of "matrix stacks". In this case we want to multiply a stack of column vectors with a stack of row vectors. First bring matrix A to shape (b, i, 1) and B to shape (b, 1, o). Then use matmul to perform b times the outer product:
import numpy as np
i, b, o = 3, 4, 5
A = np.ones((b, i))
B = np.ones((b, o))
print(np.matmul(A[:, :, np.newaxis], B[:, np.newaxis, :]).shape) # (4, 3, 5)
An alternative could be to use numpy.einsum, which can directly represent your index notation:
np.einsum('bi,bo->bio', A, B)
Why not simply
A[:, :, None] * B[:, None, :]
Depending on your convention and your dtype, you might need to throw in another np.conj somewhere. Note that np.newaxis is simply None

How to use placeholders for unneeded parameters in c++

I am using this function from the GMP arbitrary precision arithmetic library:
Function: void mpz_gcdext (mpz_t g, mpz_t s, mpz_t t, const mpz_t a, const mpz_t b)
Set g to the greatest common divisor of a and b, and in addition set s and t to coefficients satisfying a*s + b*t = g. The value in g is always positive, even if one or both of a and b are negative (or zero if both inputs are zero). The values in s and t are chosen such that normally, abs(s) < abs(b) / (2 g) and abs(t) < abs(a) / (2 g), and these relations define s and t uniquely. There are a few exceptional cases:
If abs(a) = abs(b), then s = 0, t = sgn(b).
Otherwise, s = sgn(a) if b = 0 or abs(b) = 2 g, and t = sgn(b) if a = 0 or abs(a) = 2 g.
In all cases, s = 0 if and only if g = abs(b), i.e., if b divides a or a = b = 0.
If t is NULL then that value is not computed.
I do not need the values of 'g' or 't' and would not like to create variables for the sole purpose of passing to this function. What can I do to pass something like a placeholder to this specific function, and how can I do this in c++ in general?
You might overload the function.
void mpz_gcdext (mpz_t s, const mpz_t a, const mpz_t b)
{
mpz_t g, t;
// initialize g and t as needed
mpz_gcdext(g, s, t, a, b);
}
Does that help?