0

I am totally new with python and really don't know how to solve my problem. So it would be really nice if you could explain in detail how I could solve this:

So I filtered all the coordinates of white pixels of an image and have them in a numpy array [x y] now. When I plot them I get the resulting point cloud. In this point cloud there is minimum 1 y-Value for every x-Value. Now I would like to filter this array and get a new one only with those points that have the highest y-Value for every existing x-value in there. Or you could say I just want to preserve the upper margin of my point cloud. You could illustrate it graphically as follows:

enter image description here

My point cloud array is called "Pixelpunktwolke" what means "pixel point cloud" in German

Pixelpunktwolke = np.argwhere(Maskenbild == 255) #"Maskenbild" is my image; here I detect all coordinates of white Pixels
x1=Pixelpunktwolke[:,1] #these are my x-values of my point cloud
y1=Pixelpunktwolke[:,0] #these are my y-values of my point cloud

Thank you for any help!

Mr. T
  • 11,960
  • 10
  • 32
  • 54
OrbisX
  • 35
  • 7

2 Answers2

0

I'm not sure I understand. If Pixelpunktwolke is an n x m matrix and you want to find the maximum value on each column you can try

all_ymax = np.amax(Pixelpunktwolke, axis=1)

EDIT

There is definitely a better way to do this but this should work

u, s = np.unique(Pixelpunktwolke[:,0], return_index=True)
w = np.split(Pixelpunktwolke[:,1], s[1:])
all_max = [max(i) for i in w]

EDIT 2

This is my test data:

import numpy as np

x = np.array((2,2,1,4,2,3,3,4,5,6,6,6,6,7,8,9,9))
y = np.array((2,3,4,6,2,5,8,2,5,8,1,3,6,9,0,1,1))

Pixelpunktwolke = np.column_stack((y,x))
Pixelpunktwolke = Pixelpunktwolke[Pixelpunktwolke[:,1].argsort()]

And then

s = np.unique(Pixelpunktwolke[:,1], return_index=False)
w = np.split(Pixelpunktwolke[:,0],s[1:])

all_max = [max(i) for i in w]
all_max

maxval_array = np.column_stack((all_max, np.unique(x[:,1])))
maxval_array

>array([[4, 1],
       [3, 2],
       [2, 3],
       [5, 4],
       [8, 5],
       [6, 6],
       [2, 7],
       [5, 8],
       [9, 9]])

Certainly not the most elegant way to do it, but we should be there

Leonardo
  • 2,439
  • 33
  • 17
  • 31
  • First of all thank you for your answer! "Pixelpunktwolke" has two columns: one for x-values and the second one for corresponding y-values since those are coordinates of points for a cloud. A lot of those points have the same x-value but different y-values. And I only want to preserve those points with the highest y-value for the corresponding x-value...see image above – OrbisX Jan 24 '21 at 17:31
  • sorry, i read now that you have y's on column 0 and x's on column 1, so my indices must be swapped! – Leonardo Jan 24 '21 at 18:06
  • I swapped 0's and 1's but it says "too many indices for array: array is 1-dimensional, but 2 were indexed" – OrbisX Jan 24 '21 at 18:16
  • 1
    OrbisX, what Leonardo was trying to do is [this approach](https://stackoverflow.com/a/30003565/8881141). This requires that you sort first your numy array for x-values which may or may not be desired given your data. – Mr. T Jan 24 '21 at 18:24
  • To understand why my approach fails you should provide a sample of your data. I show you mine in a new edit – Leonardo Jan 24 '21 at 18:26
  • @Mr.T, you are absolutely right! I can try to fix – Leonardo Jan 24 '21 at 18:28
  • BTW, the output should probably still be a numpy array of x-y pairs. – Mr. T Jan 24 '21 at 18:30
0

If you can sort your values without problems (this is not specified in your question), then you could sort for both, x and y, then identify the first index for each unique value to take the element before these indexes:

import numpy as np

#sample data
np.random.seed(123)
n=10
arr = np.random.randint(1, 100, (n, 2))
arr[:,1] = np.random.randint(1, 10, n)

#sort for x, then y values
arr_sort = arr[np.lexsort((arr[:,0], arr[:,1]))]
#get index for unique values
_, ind = np.unique(arr_sort[:,1], return_index=True)
ind[0] = arr.shape[0]

res = arr_sort[np.roll(ind, -1) -1]

Sample output:

[[99  2]
 [97  3]
 [87  4]
 [79  5]
 [84  8]
 [97  9]]
Mr. T
  • 11,960
  • 10
  • 32
  • 54