When we retrieve the vertices of a RotatedRect in OpenCV with rect.points(pts), what is the order of the vertices being picked. In other words, which vertex is the first element in output vector pts? Is there any general principle or just random?
While passing the points to a RotatedRect, the points can be in any arbitrary order. For a given set of points the Output would always be consistent for any random arrangement of fixed set of points.
Related
I have computed the contours of an object in an image. Now I have a 2D array, each of element representing X & Y coordinates of a contour point.
Now, I want to compute a tangent vector over each point and angle between them (contour point and tangent vector).
My points are ordered. i.e. p[i+1,] is next to p[i,] and my path is closed. i.e. p[0] is next to p[N-1] (If I consider N points. The image of contour points is attached below.
I have done a lot of search but never find any clue. Any help would be highly appreciated. Thanks.
The trivial way is :
Tangent[i] = Normalize(Contour[i+1] - Contour[i-1])
You would simply need to take care of boundary conditions if any!
Right now I am trying to understand the values within an ARKit transform matrix so I can quantify the movements of my SCNNode. From a previous post on stack overflow I have learned that the matrix contains information regarding the node's current translation, scale, rotation, and position.
What I am not understanding is which values are specifically associated with those four things. For example I have figured out that the first element of the 3rd column represents an X (horizontal) movement on the screen and the 2nd value of the 3rd column represents a Y (vertical) movement. But other than that I'm not sure what the rest of the values in the matrix mean.
Thanks for the help!
In a transformation matrix, the translation information is in the last column.
Given a transformation matrix, you can extract the translation from the last column as below:
let translation = SCNVector3(transform.columns.3.x, transform.columns.3.y, transform.columns.3.z)
Rotation and scaling use the first three columns and are more complex.
Scale is the length of the first three column vectors, and to extract the rotation you need to divide the first three column vectors by the scaling factors just mentioned.
You can refer to this link for a better understanding of scale and rotation and how to extract them.
MohammadRF's answered cleared things up for me the best. However, ARKit's matrices are in row-major order so if you were to transpose the matrices from the information he gave then it would apply to ARKit.
I am trying to estimate camera pose (with scale) from a 2D sequence. I use the following code to estimate the relative pose for each adjacent pair of images in my sequence:
Mat essentialMatrix = findEssentialMat(pointsB, pointsA, focalLength, principlePoint, RANSAC, 0.999, 1.0, mask);
recoverPose(essentialMatrix, pointsB, pointsA, rotationEstimate, translationEstimate, focalLength, principlePoint);
pointsA and pointsB are the 2D locations of features in frame A and frame B.
I would like to calculate the transformations for each frame, to obtain the world coordinate. To do this, I will be concatenating the relative pose matrices together. However, before concatenation I need to determine the relative scale.
My question is, how do I calculate the relative scale of relative poses in an image sequence? Can I utilize the solvePnPRANSAC API?
A bit late though. But the simplest solution is to take a pair of images and two features in those. Then triangulate the features in respective images frames and then take the vector pointing from the first feature to the second one in the respective frames and take the ratios.I think that will solve the problem.
I have a blurry image with a sharp edge and I want to use the profile of that sharp edge to estimate the point spread function (PSF) of the imaging system (assuming that it is symmetric). The profile of the edge gives me the "edge spread function" (ESF) and the derivative of that gives me the "line spread function" (LSF). I am trying to follow these directions that I found in an old paper on how to convert from the LSF to the PSF:
"If we form the one-dimensional Fourier transform of the LSF and rotate the resulting curve about its vertical axis, the surface thus generated proves to be the two-dimensional fourier transform of the PSF. Hence it is merely necessary to take a two-dimensional inverse Fourier transform to obtain the PSF"
I can't seem to get this to work. The 2D FFT of a PSF-like function (for example a 2d gaussian) has lots of alternative positive and negative values, but if I rotate a 1D FFT, I get concentric rings of positive or negative values and the inverse transform looks nothing like a point-spread function. Am I missing a step or misunderstanding something? Any help would be appreciated! Thanks!
Edit: Here is some code showing my attempt to follow the procedure described
;generate x array
x=findgen(1000)/999*50-25
;generate gaussian test function in 1D
;P[0] = peak value
;P[1] = centroid
;P[2] = sigma
;P[3] = base level
P=[1.0,0.0,4.0,0.0]
test1d=gaussian_1d(x,P)
;Take the FFT of the test function
fft1d=fft(test1d)
;create an array with the frequency values for the FFT array, following the conventions used by IDL
;This piece of code to find freq is straight from IDL documentation: http://www.exelisvis.com/docs/FFT.html
N=n_elements(fft1d)
T=x[1]-x[0] ;T = sampling interval
fftx=(findgen((N-1)/2)+1)
is_N_even=(N MOD 2) EQ 0
if (is_N_even) then $
freq=[0.0,fftx,N/2,-N/2+fftx]/(N*T) $
else $
freq=[0.0,fftx,-(N/2+1)+fftx]/(N*T)
;Create a 1000x1000 array where each element holds the distance from the center
dim=1000
center=[(dim-1)/2.0,(dim-1)/2.0]
xarray=cmreplicate(findgen(dim),dim)
yarray=transpose(cmreplicate(findgen(dim),dim))
rarray=sqrt((xarray-center[0])^2+(yarray-center[1])^2)
rarray=rarray/max(rarray)*max(freq) ;scale rarray so max value is equal to highest freq in 1D FFT
;rotate the 1d FFT about zero to get a 2d array by interpolating the 1D function to the frequency values in the 2d array
fft2d=rarray*0.0
fft2d(findgen(n_elements(rarray)))=interpol(fft1d,freq,rarray(findgen(n_elements(rarray))))
;Take the inverse fourier transform of the 2d array
psf=fft(fft2d,/inverse)
;shift the PSF to be centered in the image
psf=shift(psf,500,500)
window,0,xsize=1000,ysize=1000
tvscl,abs(psf) ;visualize the absolute value of the result from the inverse 2d FFT
I don't know IDL, but I think your problem here is that you're taking the FFT of signals that are centered, where by default the function expects 0-frequency components at the beginning of the array.
A quick search for the proper way to do this in IDL indicates the CENTER keyword is what you're looking for.
CENTER
Set this keyword to shift the zero-frequency component to the center of the spectrum. In the forward direction, the resulting Fourier transform has the zero-frequency component shifted to the center of the array. In the reverse direction, the input is assumed to be a centered Fourier transform, and the coefficients are shifted back before performing the inverse transform.
Without letting the FFT routine know where the center of your signal is, it will seem shifted by N/2. In the converse domain this is a strong phase shift that will appear as if values are alternating positive and negative.
Ok, looks like I have solved the problem. The main issue seems to be that I needed to use the absolute value of the FFT results, rather than the complex array that is returned by default. Using the /CENTER keyword also helped make the indexing of the FFT result much simpler than IDL's default. Here is the working version of the code:
;generate x array
x=findgen(1000)/999*50-25
;generate lorentzian test function in 1D
;P[0] = peak value
;P[1] = centroid
;P[2] = fwhm
;P[3] = base level
P=[1.0,0.0,2,0.0]
test1d=lorentzian_1d(x,P)
;Take the FFT of the test function
fft1d=abs(fft(test1d,/center))
;Create an array of frequencies corresponding to the FFT result
N=n_elements(fft1d)
T=x[1]-x[0] ;T = sampling interval
freq=findgen(N)/(N*T)-N/(2*N*T)
;Create an array where each element holds the distance from the center
dim=1000
center=[(dim-1)/2.0,(dim-1)/2.0]
xarray=cmreplicate(findgen(dim),dim)
yarray=transpose(cmreplicate(findgen(dim),dim))
rarray=sqrt((xarray-center[0])^2+(yarray-center[1])^2)
rarray=rarray/max(rarray)*max(freq) ;scale rarray so max value is equal to highest freq in 1D FFT
;rotate the 1d FFT about zero to get a 2d array by interpolating the 1D function to the frequency values in the 2d array
fft2d=rarray*0.0
fft2d(findgen(n_elements(rarray)))=interpol(fft1d,freq,rarray(findgen(n_elements(rarray))))
;Take the inverse fourier transform of the 2d array
psf=abs(fft(fft2d,/inverse,/center))
;shift the PSF to be centered in the image
psf=shift(psf,dim/2.0,dim/2.0)
psf=psf/max(psf)
window,0,xsize=1000,ysize=1000
tvscl,real_part(psf) ;visualize the resulting PSF
;Test the performance by integrating the PSF in one dimension to recover the LSF
psftotal=total(psf,1)
plot,x*sqrt(2),psftotal/max(psftotal),thick=2,linestyle=2
oplot,x,test1d
Using OpenCV's findContours() I have a list of contours in an image. I'm interested only in the straight lines, so if they are too 'squiggly' they should be rejected. The question is how to evaluate how straight each contour is?
I looked at fitLine(), but there doesn't appear to be a goodness-of-fit measure returned. I could evaluate this myself using the returned line.
I looked at arcLength() with the aim to compare this to the bounding rectangle dimensions, but even for somewhat straight lines, the arc length can be relatively long if the contour points are dense.
I could find the convex hull and compare to the bounding rectangle dimensions, but I'd have to analyze the convexity defects.
Is there a moment that would be useful here?
Find the contours as you are doing now
Find the straight lines in the image using HoughLines()
Compute the overlap between the contours and the straight lines
Take two points (with for instance cv::approxPoly) on your contour and compute their absolute distance. Then go through the contour points between the two points and add up all the distances. If the difference between distance over the contour and the absolute distance is bigger than a certain threshold you can reject it.
The function, findContours() already approximated contours with line segments somehow. Each contour is represented by a list of points around it. For your purpose, simply computing the distances of each pair of consecutive points in the contour would give you all line segment lengths.
Here is an example:
c = cnts[0]
#d is the points in contour c shifted by one with wraparound (numpy.roll)
d = np.roll(c, 1, axis=0)
np.linalg.norm(c - d, axis = -1)