Related
I have some points which illustrates heads of pedestrians during an experiment in each frame. I need to calculate which Voronoi Cells are in specific area - measurement square:
x_range = (-0.4, 0.4)
y_range = (0.5, 1.3)
So I've adapted a sample of generating Voronoi cells from points + I've added measurement area (blue lines) and walls (black), here is result for frame 0:
And here is part of code (adapted from the sample):
entries_for_frame = get_entries_at_frame(entries, frame)
points = points_from_entries(entries_for_frame)
vor = scipy.spatial.Voronoi(points)
scipy.spatial.voronoi_plot_2d(vor)
plt.show()
As I know in order to calculate which cells are inside the measurement area I need to check which lines of cells are crossing with the measurement square or are inside its.
So according to the documentation of scipy.spatial.Voronoi the interesting attributes are: vertices, which is returning those orange vertices. I need also to have edges of vertices inside the measurement area, the attribute according to the documentation of scipy.spatial.Voronoi is ridge_vertices, but unfortunately it is returning something strange:
[[0, 19], [0, 2], [1, 17], [1, 3], [2, 3], [17, 19], [-1, 22], [-1, 15], [15, 16], [16, 21], [21, 22], [-1, 0], [2, 23], [22, 23], [28, 32], [28, 29], [29, 30], [30, 31], [31, 32], [12, 13], [12, 28], [13, 25], [25, 29], [-1, 24], [-1, 31], [24, 30], [-1, 26], [26, 27], [27, 32], [-1, 33], [19, 20], [20, 34], [33, 34], [35, 36], [-1, 35], [36, 37], [-1, 37], [-1, 4], [4, 5], [5, 35], [6, 37], [6, 7], [7, 36], [38, 39], [38, 40], [39, 41], [40, 41], [-1, 40], [-1, 8], [8, 38], [-1, 9], [9, 10], [10, 41], [10, 43], [39, 42], [42, 43], [52, 53], [52, 57], [53, 54], [54, 55], [55, 56], [56, 57], [13, 52], [25, 57], [48, 49], [48, 54], [49, 55], [9, 50], [24, 56], [49, 50], [17, 59], [18, 61], [18, 20], [59, 61], [11, 46], [11, 60], [18, 47], [46, 47], [60, 61], [58, 63], [58, 60], [59, 62], [62, 63], [26, 64], [27, 65], [64, 65], [21, 67], [23, 68], [67, 68], [42, 45], [43, 69], [44, 45], [44, 72], [69, 72], [50, 70], [69, 70], [48, 71], [70, 71], [4, 76], [5, 75], [75, 76], [33, 77], [76, 77], [34, 78], [77, 78], [47, 79], [78, 79], [80, 82], [80, 81], [81, 83], [82, 84], [83, 84], [14, 53], [14, 80], [71, 82], [72, 84], [14, 51], [51, 87], [81, 85], [85, 87], [88, 90], [88, 89], [89, 93], [90, 91], [91, 92], [92, 93], [44, 88], [83, 89], [85, 86], [86, 93], [11, 91], [58, 92], [94, 95], [94, 97], [95, 96], [96, 98], [97, 99], [98, 99], [12, 94], [51, 95], [65, 97], [101, 104], [101, 102], [102, 103], [103, 105], [104, 105], [15, 101], [16, 104], [64, 102], [99, 103], [66, 67], [66, 105], [1, 106], [3, 107], [106, 107], [68, 108], [107, 108], [8, 73], [45, 109], [73, 110], [109, 110], [111, 115], [111, 113], [112, 113], [112, 114], [114, 115], [46, 74], [74, 111], [79, 113], [75, 112], [7, 114], [116, 117], [116, 118], [117, 120], [118, 119], [119, 121], [120, 121], [96, 118], [98, 100], [100, 116], [87, 119], [86, 121], [63, 120], [122, 127], [122, 123], [123, 124], [124, 125], [125, 126], [126, 127], [100, 127], [117, 122], [62, 123], [106, 124], [108, 125], [66, 126], [128, 129], [128, 130], [129, 132], [130, 131], [131, 133], [132, 134], [133, 134], [90, 128], [109, 129], [74, 130], [110, 132], [115, 131], [6, 133], [73, 134]]
In documentation I don't see how to understand returned numbers. Also in tutorials in explaining how to solve my problem. So my question is: how to calculate which Voronoi cells are inside the measurement area with at least single point?
I believe that your best bet is to use some kind of multiple polygon intersection algorithm using the cell vertices to describe the polygons.
You can whittle down the number of polygons by discarding those whose rightmost vertex is left of the blue rectangle, those whose leftmost vertex is to the right, and so on for up and down. This leaves you with the yellow polygons only.
You can also quickly eliminate (only, in this case you mark them as "intersecting") all those whose center or vertex lies inside the rectangle. This also is very quick.
In this example this is enough to locate all cells.
In other cases (for example, in the figure below, if the bottom-left yellow cell was shifted slightly upwards) you will have cells that have all vertices and the Delaunay center outside the rectangle, and yet one edge crosses it, so there is an intersection. To recognize those, you can exploit the fact that a rectangle is a convex figure, and check whether, among the cells you've left, there is one that contains at least one of the rectangle's corners. This is a slightly more complex check ("whether a point lies inside a convex polygon"), but not too complex since the cell is also convex and can be trivially decomposed in triangles.
The pseudo algorithm would be:
for all Voronoi cells:
get list of vertices.
are they all left/below/above/right of the rectangle?
YES: this cell does not intersect. Continue.
for all the vertices plus the cell center:
is this point inside the rectangle?
YES: we have intersection. Report this cell and continue.
decompose the cell in a list of triangles with vertex in the
Delaunay center, taking ordered vertex pairs.
for each triangle
for each vertex of the rectangle
is the vertex inside the triangle?
YES: we have intersection. Report and continue
this cell does not intersect the rectangle.
I am actually doing deep learning on white spots images. Thanks to my model I predict a list of points with [x, y] coordinates. I have also a list of the target points with [x', y'] coordinates.
My goal is to compute the euclidean distance between the predicted and the target coordinates.
The length of the list of my predictions is smaller than the list of the targets.
Predictions
[[11, 25], [13, 82], [27, 42], [32, 107], [37, 72], [38, 120], [40, 29], [55, 89], [62, 12], [80, 20], [83, 67], [ 86, 108], [94, 23], [107, 56], [108, 38], [111, 89], [115, 36], [116, 52], [116, 121], [119, 57]]
Targets
[[11, 25], [13, 82], [27, 42], [32, 107], [37, 72], [38, 120], [40, 29], [55, 89], [56, 124], [61, 122], [62, 12], [ 81, 120], [83, 67], [86, 108], [89, 124], [92, 1], [94, 23], [107, 56], [107, 39], [111, 89], [115, 36], [116, 120], [117, 51], [118, 56]]
What I want is to sort the arrays of Targets by having their predictions at the same position in the target list of coordinates and hence, having the non-predicted coordinates at the end of the target list.
I have already tried to compute the euclidean distance for each element of the targets by looking at the predictions and taking the lower distance under a threshold to sort the array. The problem I have is that when you have 2 predicted points close to each other and 2 target points related to that prediction, and one of the predicted points is closer to both of the targets than the other prediction, my code does not work.
# Align predictions targets in increasing order for the x parameter, the targets not predicted will be at the end of the target list
def align_by_dist(a_sorted, b_sorted):
for i in range(len(b_sorted)):
D = []
for j in range(len(a_sorted)):
dist = distance.euclidean(a_sorted[j], b_sorted[i])
if dist < 7: # Select a treshold for the euclidean distance
D.append(dist) # Append the euclidean distance which is lower than the treshold
if dist == min(D): # Check if it is the lower euclidean distance between the close micro-bubb
b_sorted[j], b_sorted[i] = b_sorted[i], b_sorted[j]
# If it is the lowest euclidean distance, put at the same level the target micro-bubble
# and its closest predicted micro-bubble
return a_sorted, b_sorted
a_sorted is the list of predictions and b_sorted is the list of targets.
Here I know that my code only returned a vector with the targets that have a prediction but it is the first step.
The code work in general but here I gave an example where it is not working. The point at [116, 52] is the predictions of the target at [117, 51] but my output is:
[[11, 25], [13, 82], [27, 42], [32, 107], [37, 72], [38, 120], [40, 29], [55, 89], [62, 12], [81, 120], [83, 67], [86, 108], [94, 23], [107, 56], [107, 39], [111, 89], [115, 36], [118, 56], [116, 120], [92, 1], [56, 124], [89, 124], [61, 122], [117, 51]]
Thank you for your help.
I may have succeeded with this modification of my code:
def align_by_dist(A, B):
for i in range(len(A)):
D = [] # This list will contain the index where the euclidean distance is lower than the threshold
for j in range(len(B)):
dist = distance.euclidean(A[i], B[j]) # Compute the euclidean distance between a target at index j and a prediction at index I
if dist <= 4: # Select a treshold for the euclidean distance
D.append(np.array([dist,j,i])) # Append the euclidean distance and the index of the target and prediction vector
if D: # If we find an euclidean distance lower than the threshold we can now sort for the index i the list of prediction
D_sorted = sorted(D,key=lambda elem:elem[0]) # We sort the array of distance lower than the threshold to get the minimum distance for the index I
value = D_sorted[0]
B[value[2].astype(np.int64)], B[value[1].astype(np.int64)] = B[value[1].astype(np.int64)], B[value[2].astype(np.int64)] # We updated the target list position
A[value[2].astype(np.int64)] = [1000000,1000000] # We set the value of the predictions very high to not have duplicates when sorting the targets coordinates
return B
I have created tif image using matplotlib python trigulation function, Now tif need to be change to goetiff with epsg4326 projection with removing the background only the patch need to be there.
What difficulty i am facing :-
1- projection change is not happening correct.
2- pixel value should be z parameter value.
3- only the clip of lat lon i want not the whole lat lon area.
CODES:-
1- For creating matplotlib trigulation tiff code below
#MAKING TIFF FILE USING TRIANGULARION MATPLOTLIB.
import matplotlib.tri as mtri
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
def plot():
x=np.random.uniform(70,94,74)
y=np.random.uniform(8,22,74)
# A selected triangulation of the points.
triangles = np.asarray([
[67, 66, 1], [65, 2, 66], [1, 66, 2], [64, 2, 65], [63, 3, 64],
[60, 59, 57], [2, 64, 3], [3, 63, 4], [0, 67, 1], [62, 4, 63],
[57, 59, 56], [59, 58, 56], [61, 60, 69], [57, 69, 60], [4, 62, 68],
[6, 5, 9], [61, 68, 62], [69, 68, 61], [9, 5, 70], [6, 8, 7],
[4, 70, 5], [8, 6, 9], [56, 69, 57], [69, 56, 52], [70, 10, 9],
[54, 53, 55], [56, 55, 53], [68, 70, 4], [52, 56, 53], [11, 10, 12],
[69, 71, 68], [68, 13, 70], [10, 70, 13], [51, 50, 52], [13, 68, 71],
[52, 71, 69], [12, 10, 13], [71, 52, 50], [71, 14, 13], [50, 49, 71],
[49, 48, 71], [14, 16, 15], [14, 71, 48], [17, 19, 18], [17, 20, 19],
[48, 16, 14], [48, 47, 16], [47, 46, 16], [16, 46, 45], [23, 22, 24],
[21, 24, 22], [17, 16, 45], [20, 17, 45], [21, 25, 24], [27, 26, 28],
[20, 72, 21], [25, 21, 72], [45, 72, 20], [25, 28, 26], [44, 73, 45],
[72, 45, 73], [28, 25, 29], [29, 25, 31], [43, 73, 44], [73, 43, 40],
[72, 73, 39], [72, 31, 25], [42, 40, 43], [31, 30, 29], [39, 73, 40],
[42, 41, 40], [72, 33, 31], [32, 31, 33], [39, 38, 72], [33, 72, 38],
[33, 38, 34], [37, 35, 38], [34, 38, 35], [35, 37, 36]])
z = np.random.uniform(0.5, 8, 74)
triang = mtri.Triangulation(x, y, triangles=triangles)
print("type(triang):", triang)
print("type(z):", type(z))
ax=plt.tripcolor(triang,z,vmin=0,vmax=2)
ax
plt.savefig("ax.tif")
plt.show(ax)
plot()
2- making geotiff with projection from tif
from osgeo import gdal, osr
import numpy, gdal
ds = gdal.Open('ax.tif')
band = ds.GetRasterBand(1)
myarray = numpy.array(band.ReadAsArray())
convert=lambda x:x*(0.0124796)
myarray=convert(myarray)
#print("myarray:",myarray)
selection = numpy.logical_or(myarray >= 3.5, myarray <= 7)
new_array = [ [0 for i in range(band.XSize)] for j in range(band.YSize)]
for i, item in enumerate(myarray):
for j, element in enumerate(item):
if selection[i][j] == True:
new_array[i][j] = myarray[i][j]
else:
new_array[i][j] = -999
if new_array[i][j]==3.182298:
new_array[i][j] = -999
geotransform = ds.GetGeoTransform()
wkt = ds.GetProjection()
# Create gtif file
driver = gdal.GetDriverByName("GTiff")
output_file = "ax_geotiff.tif"
dst_ds = driver.Create(output_file,
band.XSize,
band.YSize,
1,
gdal.GDT_Float64)
new_array = numpy.array(new_array)
print(type(new_array[i]))
#new_array[i]=new_array.max())
#transformed_arr = np.where(arr<5, arr*10, 0)
#new_array=numpy.where(new_array[i]==new_array.max(),-999,new_array)
print("new_array:",new_array)
#writting output raster
dst_ds.GetRasterBand(1).WriteArray( new_array )
#setting nodata value
dst_ds.GetRasterBand(1).SetNoDataValue(-999)
#setting extension of output raster
# top left x, w-e pixel resolution, rotation, top left y, rotation, n-s pixel resolution
dst_ds.SetGeoTransform(geotransform)
# setting spatial reference of output raster
srs = osr.SpatialReference()
srs.ImportFromEPSG(4326)
#srs = osr.SpatialReference()
#srs.ImportFromWkt(wkt)
dst_ds.SetProjection( srs.ExportToWkt() )
#Close output raster dataset
ds = None
dst_ds = None
print(numpy.unique(new_array))
3- To plot the geotiff
#CHECKING THE TIFF FILE / ANALYSING THE TIFF FILE DATA AND PLOT.
#tttraster_geotiff
import gdal
%matplotlib inline
import rasterio
from matplotlib import pyplot
import numpy
ds = gdal.Open('ax_geotiff.tif')
band = ds.GetRasterBand(1)
myarray = numpy.array(band.ReadAsArray())
print(myarray)
pyplot.imshow(myarray, cmap='pink')
pyplot.show()
##Above is the sample data and codes i am using but i am not getting correct epsg 4326 projection and my background color in geottiff blue color is coming if i select cmap='jet' i.e blue color large part of geotiff plot indicate the mav value of z parameter , those blue color if i change to np.nan then i a not able to see the other,
so what all modification i have to do-
1- correct projection
2- remove only the blue color as nan color.enter image description here
enter image description here
3- want to remove that drak red color(max value of z variable) , only the map plot i want.
enter image description here
In the array:
np.random.randint(100, size=(10, 2))
array([[ 8, 31],
[96, 97],
[26, 31],
[81, 70],
[47, 97],
[95, 84],
[11, 93],
[31, 77],
[25, 45],
[79, 22]])
I´d like to obtain [8, 22], the minimum values of each column.
How can I get it?
I'm just putting #gtlambert's comment into an answer, since it's probably the best choice. Use the array.min function
x = array([[ 8, 31],
[96, 97],
[26, 31],
[81, 70],
[47, 97],
[95, 84],
[11, 93],
[31, 77],
[25, 45],
[79, 22]])
In [6]: x.min(axis=0)
Out[6]: array([ 8, 22])
Probably not the most efficient, but...
left = np.array([])
right = np.array([])
for n in aaa:
left = np.append(left,n[0])
right = np.append(right,n[1])
sol = [np.min(left), np.min(right)]
I am making a program in python and I am having an error that I cannot solve.
This is the problem:
I have a set to points in 3D space, and I am storing it in a vector(rake).
My point is to build a stream surface.
So I am appending those points to another list so that I can have all the points from the "line" before.
The rake list has this format:
[[60, 0, 50], [63, 3, 50], [66, 6, 50], [69, 9, 50], [72, 12, 50],
[75, 15, 50], [78, 18, 50], [81, 21, 50], [84, 24, 50], [87, 27, 50],
[90, 30, 50], [93, 33, 50], [96, 36, 50], [99, 39, 50], [102, 42, 50]]
Then when I append the points to the other list(points_list) is like this:
[[[60, 0, 50], [63, 3, 50], [66, 6, 50], [69, 9, 50], [72, 12, 50],
[75, 15, 50], [78, 18, 50], [81, 21, 50], [84, 24, 50], [87, 27, 50],
[90, 30, 50], [93, 33, 50], [96, 36, 50], [99, 39, 50], [102, 42, 50]]]
My point is that with the points_list I can know in witch iteration level I am dealing with, so that I could render the surface in the end.
When I try to get, for instance, one element from the points_arrays I have and index error.
this is the code:
points_arrays.append(rake)
for i in range(iterations):
for j in range(rlength):
print points_arrays[i][j][0],points_arrays[i][j][1],points_arrays[i][j][1]
When I run this part of the code I am able to get the points but in the end I get an index error. (IndexError: list index out of range)
Can anyone help me to solve this??
Your main problem is that you should use extend instead of append:
points_list.extend(rake)
This is because append adds a single object to the end of the list. In this case it means that the entire second list is appended as a single element.
append - append object to end
extend - extend list by appending elements from the iterable
You should also be aware of the following points that are not directly related to your problem:
In Python the object created when you write [1, 2, 3] is called a list, not an array.
Your print statement is wrong. The second occurrence of points_arrays[i][j][1] should be points_arrays[i][j][2]
for rake in points_list:
for point in rake:
print point[0], point[1], point[2]
If you want to use numbers as indexes:
for npoint in xrange(len(points_list))
for nrake in xrange(len(points_list[npoint]))
print points_list[npoint][nrake][0], points_list[npoint][nrake][1], points_list[npoint][nrake][2]