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 want to make 2D array, which is 50X75.
Computer has to make random coordinates inside the array, about 15 to 20 coordinates.
What should I do TT
I stopped with the first step, making 50X75 2D array, so help meTT
You can generate 2D array using random runmbers
from random import randint
coordinates = [[randint(1, 100), randint(1, 100)] for i in range(20)]
Output: [[81, 52], [12, 79], [24, 90], [93, 53], [98, 17], [40, 44], [31, 1], [1, 40], [8, 34], [81, 31], [87, 50], [45, 72], [86, 70], [43, 78], [64, 80], [85, 76], [28, 43], [81, 78], [80, 55], [82, 58]]
A 50 x 75 2D array can be made using a np.reshape function. Here is an example, hope this helps.
import numpy as np
np.arange(3750).reshape(50, 75) # the array has 50 rows and 75 cols
array([[ 0, 1, 2, ..., 72, 73, 74],
[ 75, 76, 77, ..., 147, 148, 149],
[ 150, 151, 152, ..., 222, 223, 224],
...,
[3525, 3526, 3527, ..., 3597, 3598, 3599],
[3600, 3601, 3602, ..., 3672, 3673, 3674],
[3675, 3676, 3677, ..., 3747, 3748, 3749]])
What is the easiest way to obtain a 'key' point set from some string text in Python? Please see the example. Key points are highlighted with blue and yellow.
I need to build 3D figure based on this set later.
So for a 3D Model you perhaps need more than only some few points think about the letter "S". Created some code to get generic the coordinates. You can play around with the size of the font, and picture size, to get more or less points. The arial.ttf was downloaded from https://github.com/JotJunior/PHP-Boleto-ZF2/blob/master/public/assets/fonts/arial.ttf
from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont
import numpy as np
import cv2
print np.__version__
def getPixelColor(pixel, x, y):
try:
return pixel[x,y]
except IndexError:
return (255,255,255)
def hasNeighbourColor(color, pixels, x, y):
if getPixelColor(pixels,x-1,y-1) == color or getPixelColor(pixels,x,y-1) == color or getPixelColor(pixels,x+1,y-1) == color \
or getPixelColor(pixels,x-1,y) == color or getPixelColor(pixels,x+1,y) == color\
or getPixelColor(pixels,x-1,y+1) == color or getPixelColor(pixels,x,y+1) == color or getPixelColor(pixels,x+1,y+1) == color:
return True
return False
def createMapOfLetter(letter):
print "LETTER %s:" % letter
print "---------"
img = Image.new('RGB', (230, 230), "white")
d = ImageDraw.Draw(img)
font = ImageFont.truetype("arial.ttf", 300)
d.text((15, -50), letter, fill=(0, 0, 0), font=font)
img.save('letter-%s.png' % letter, 'png')
pixels = img.load()
ans = []
for x in range(230):
for y in range(230):
if pixels[x,y] == (0,0,0):
if hasNeighbourColor((255,255,255), pixels, x, y) and not hasNeighbourColor((255,0,0), pixels, x, y):
pixels[x,y] = (255,0,0)
ans.append([x,y])
for x in range(230):
for y in range(230):
if pixels[x,y] != (255,0,0):
pixels[x,y] = (255,255,255)
img.save('letter_map-%s.png' % letter, 'png')
print ans
createMapOfLetter('A')
The script creates the letter-[letter].png which looks like this. Left A right S
And then creates a list of coordinates. The coordinates in a picture look like this. The script automatically creates a letter_map-[letter].png. Left A, Right S
The output of the coordinates for A look like this it.
[[15, 221], [17, 215], [17, 221], [19, 221], [21, 221], [22, 202], [23, 221], [25, 194], [25, 221], [27, 221],
[29, 221], [30, 181], [31, 221], [33, 173], [33, 221], [35, 221], [37, 221], [38, 160], [39, 221], [41, 152],
[41, 221], [43, 221], [45, 218], [46, 139], [49, 131], [52, 198], [53, 195], [54, 118], [54, 192], [57, 110],
[61, 172], [62, 97], [62, 169], [63, 166], [65, 89], [67, 156], [69, 156], [70, 76], [71, 156], [73, 68],
[73, 156], [75, 156], [76, 134], [77, 129], [77, 156], [78, 55], [78, 134], [79, 156], [80, 134], [81, 47],
[81, 118], [81, 156], [82, 134], [83, 156], [84, 134], [85, 107], [85, 156], [86, 34], [86, 134], [87, 156],
[88, 134], [89, 26], [89, 96], [89, 156], [90, 134], [91, 156], [92, 134], [93, 85], [93, 156], [94, 13], [94, 134],
[95, 156], [96, 134], [97, 7], [97, 74], [97, 156], [98, 71], [98, 134], [99, 7], [99, 156], [100, 134], [101, 7],
[101, 156], [102, 134], [103, 7], [103, 56], [103, 156], [104, 134], [105, 7], [105, 156], [106, 46], [106, 134],
[107, 7], [107, 156], [108, 134], [109, 7], [109, 35], [109, 156], [110, 31], [110, 134], [111, 7], [111, 156],
[112, 134], [113, 7], [113, 156], [114, 37], [114, 134], [115, 7], [115, 40], [115, 156], [116, 43], [116, 134],
[117, 7], [117, 46], [117, 156], [118, 49], [118, 134], [119, 7], [119, 156], [120, 134], [121, 7], [121, 156],
[122, 134], [123, 7], [123, 63], [123, 156], [124, 66], [124, 134], [125, 7], [125, 156], [126, 134], [127, 74],
[127, 156], [128, 134], [129, 156], [130, 134], [131, 85], [131, 156], [132, 134], [133, 156], [134, 134], [135, 96],
[135, 156], [136, 134], [137, 32], [137, 156], [138, 104], [138, 134], [139, 37], [139, 156], [140, 134], [141, 42],
[141, 156], [142, 115], [142, 134], [143, 47], [143, 156], [144, 134], [145, 52], [145, 123], [145, 156], [146, 134],
[147, 57], [147, 156], [148, 134], [149, 62], [149, 156], [151, 67], [151, 156], [153, 72], [153, 156], [155, 77],
[155, 156], [157, 82], [157, 156], [159, 87], [160, 161], [164, 172], [168, 183], [171, 191], [175, 202], [178, 210],
[180, 139], [182, 144], [182, 221], [184, 149], [184, 221], [186, 154], [186, 221], [188, 159], [188, 221], [190, 164],
[190, 221], [192, 169], [192, 221], [194, 174], [194, 221], [196, 179], [196, 221], [198, 184], [198, 221], [200, 189],
[200, 221], [202, 194], [202, 221], [204, 199], [204, 221], [206, 221], [208, 221], [210, 221], [212, 221]]
The output for the coordinates of S look like this
[[30, 162], [31, 167], [35, 179], [38, 52], [39, 187], [41, 81], [43, 193], [47, 198],
[49, 28], [52, 203], [57, 101], [57, 161], [58, 19], [61, 172], [62, 174], [64, 15],
[66, 52], [66, 68], [67, 49], [67, 181], [68, 73], [68, 108], [69, 45], [70, 76], [70, 109],
[71, 42], [71, 185], [74, 10], [75, 81], [77, 36], [78, 190], [78, 218], [80, 34], [85, 220], [86, 31],
[89, 30], [89, 116], [89, 221], [90, 88], [91, 5], [91, 196], [93, 89], [97, 4], [98, 28], [103, 120],
[107, 93], [107, 121], [111, 94], [111, 122], [127, 28], [128, 4], [130, 127], [134, 223], [135, 100],
[136, 30], [139, 6], [139, 31], [140, 130], [140, 222], [143, 131], [146, 8], [148, 133], [154, 136],
[156, 44], [157, 189], [157, 217], [159, 49], [161, 141], [162, 15], [162, 109], [163, 61], [163, 143],
[164, 110], [166, 111], [167, 149], [167, 212], [168, 19], [169, 171], [177, 118], [177, 205], [182, 200],
[188, 129], [189, 49], [190, 132], [190, 189], [195, 178], [197, 150]]
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)]