this question is related to another question i asked before here. now i have an array of contains 0s,1s,-1s. consider it as an image where background is 0s. i has groups of 1s and -1s.
This it that array opened in excel. those highlighted groups are 1s( in some cases can be -1s). there can be 4 groups in one array maximum. i want to separate those groups in to left, right, top, bottom with its value and the original index.
referring to the previous question, i am trying to find the points on the humps and hollows in the puzzle pieces. if i can group them separately then i know how to find the index of the point i want.
i tried to separate like this. but this doesn't apply for all the pieces. some times it can cut through hollows.
thanks in advance for any help!!!
Since your data is 2d array. Have you tried using an approach like region growing to segment the data?
https://en.wikipedia.org/wiki/Region_growing
Basically, you need to start with a seed point and grow the region by considering neighbouring points and whether or not they fit the criteria for your region.
Related
I am trying to segment a 2D depth image into non-overlapping rectangular areas of similar values as shown in the example:
In this example, the depth image is segmented into four rectangles: 4by3by6 yellow, 2by4by15 green, 4by2by8 orange, and 2by2by3 blue. Note that there is a min length and width limit to the rectangles, in this case, 2, so that the lower right corner is segmented into one area instead of two.
This is a simple example, the depth map can be a lot more complex than this. This is quite a challenging problem I don't expect it to be solved to optimality, but any solution more optimized than a grid of fixed resolution is appreciated.
I imagine this to be solved by some RANSAC process, similar to plane fitting, but I haven't figured out exactly how to do that. The problem also resembles image segmentation, where each segment is rectangular in shape and does not overlap.
Idea of an algorithm to solve this (not optimally ofc):
examine vertical neighbours for each element that could be grouped. Rule of grouping needs to be determined by you after some "trial and error". Single-element groups are also possible. Every element must be added to one and only one group.
iterate through groups and check whether horizontal neighbours of those are "close enough", if yes, then merge groups.
iterate through groups and check whether vertical neighbours of those are "close enough", if yes, then merge groups.
Continue steps 2 and 3 and finish when there was no single group merging during those
Finally, remove those groups that do not fulfill width/height requirements
I have a raster image with some values are nan and these are supposed to be filled by the valid values. These valid values should meet two conditions: within a certain distance to the target pixel, and are flagged as true in an input FlagMask.
The rasterio.fill.fillnodata https://rasterio.readthedocs.io/en/latest/api/rasterio.fill.html can achieve filling nodata with the distance condition but not the FlagMask condition. The inpaint in matlab https://uk.mathworks.com/matlabcentral/fileexchange/27994-inpaint-over-missing-data-in-1-d-2-d-3-d-nd-arrays works similarly as rasterio.fill.fillnodata. Would appreciate existing functions or some ideas about modifying based on some modules. An efficient algorithm will be desired as my raster input will be more than 5000*5000.
I would simply run inpaintn() and then reset those elements which are not flagged back to NaN. I'm having difficulty thinking of a scenario where the practical difference between your algorithm and my proposal is meaningful, if you have an example data set let me know.
I am writing a Python program that shows 2 thermal (low res) drone shots next to each other. The user then chooses 3 points on both pictures after which the second picture should be transformed and merged with the first. The following step the program should show the merged picture with the third picture from the flight next to it etc.
At the moment I'm looking at ways to do the transformation and merging of the images.
I was thinking of reading the images as arrays (a list of lists (= rows)), manually calculating the new location of each pixel with the transformation formula (at the moment I have calculated the transformation matrix with OpenCV), creating a new empty list of lists and pasting the pixel value in the corresponding location in the new list of lists. Afterward, I wanted to fill al the empty 'cells' with zero's.
To merge them I would again create a new list of lists and loop through both images and get the maximum or average value for each cell and filling the empty remaining 'cells' with zero's. This resulting merged image I would then show in the window next to the following image from the flight as I mentioned.
I still don't know how I'm going to predict the size of my list of lists before calculating the new coordinates of the pixel values. Also, this approach seems kind of long and inefficient so I was wondering if there is an easier way to do this using Wand or OpenCV (or any other library).
I did everything manually and it works, one problem I still have is diagonal NoData lines through the tranformed image. I suppose this is the result of the rounding of coordinates because I can't use floats (which are the result of the transformation formula) as indices in the lists. (The 3 sets of points weren't chosen super carefully for this example but you get the point.)
EDIT: I solved the diagonal lines by filling in the calculated value in the center pixels and the 8 other pixels bordering the center pixels. It makes the image blurrier but it's the only solution I've got.
I have given a large binary image (every pixel is either 1 or 0).
I know that in that image there are multiple regions (a region is defined as a set of neighboring 1s which are enclosed by 0s).
The goal is to find the largest (in terms of pixel-count or enclosed area, both would work out for me for now)
My current planned approach is to:
start an array of array of coordinates of the 1s (or 0s, whatever represents a 'hit')
until no more steps can be made:
for the current region (which is a set of coordinates) do:
see if any region interfaces with the current region, if yes add them togther, if no continue with the next iteration
My question is: is there a more efficient way of doing this, and are there already tested (bonus points for parallel or GPU-accelerated) implementations out there (in any of the big libraries) ?
You could Flood Fill every region with an unique ID, mapping the ID to the size of the region.
You want to use connected component analysis (a.k.a. labeling). It is more or less what you suggest to do, but there are extremely efficient algorithms out there. Answers to this question explain some of the algorithms. See also connected-components.
This library collects different efficient algorithms and compares them.
From within Python, you probably want to use OpenCV. cv.connectedComponentsWithStats does connected component analysis and outputs statistics, among other things the area for each connected component.
With regards to your suggestion: using coordinates of pixels rather than the original image matrix directly is highly inefficient: looking for neighbor pixels in an image is trivial, looking for the same in a list of coordinates requires expensive searchers.
I am using python 2.7
I have an array of indices created by
ids=np.indices((20,20))
ids[0] is filled with all the vertical coordinates and
ids1 is filled with all the horizontal coordinates
ids has a shape of (2,20,20)
I have a boolean mask of shape (20,20)
I need to have a list of ids that correspond to the ones marked as true in the mask.
I am trying to do this by mid=ids[:,mask].T which gives me a list of this sort
[2,17]
[4,6]
[1,19]
[18,4]
and so on. They are saved in an array called mid
Then, I need all those coordinates in mid to find the values in another array. Meaning I need
anotherarray([2,17])
I have not managed to take the list of mid to use them in a fancy indexing way, can someone help me?
I have
anotherarray[mid[0],mid[1]]
and it doesnt work. I also have
anotherarray[tuple(mid)]
and it doesn't work
Edit (read only if you care about context): I wanted to add context to show why I think I need the extra indices. Maybe I don't, that is what I want to fin out to make this efficient.
This is a registration problem, a ver simple one. I have two images. A reference and a floating as seen below. Reference to the left, and floating to the right.
The reference image and the floating image are in different coordinate spaces. I have points marked as you can see in the images. I find an affine transformation between each other.
The region delimited by the line is my region of interest. I send the coordinates of that region in the floating space to the reference space.
There in the reference space, I find what pixels are found inside the region and they become the mask array, containing the information of both in and outer pixels.
But I only care about those inside, so I want only the indices of those pixels inside the mask in the reference space and save them using mid=ids[:,mask] .
Once I have those points, I transform them back to the floating space, and in those new indices I need to look for the intensity. Those intensities are the ones who will be written back in the reference in their corresponding indices. That is why I think I need to have the indices of those points in both reference and floating space, and the intensities of the image. That other image is the anotherarray from which I want only the transformed masked pixels.
So there you go, that is the explanation if you care about it. Thank you for reading and answering.
A few tips: You can get mid directly from mask using np.argwhere(mask). Probably more convenient for your purpose is np.where which you can use like mi, mj = np.where(mask) and then anotherarray[mi, mj].