I want to extract a specific ROI out of a 3D Model that i created but i have no idea how to do this. I also performed a binary segmentation on one of the images i used for the mesh generation. Now i want to cut out my segmented region out of the mesh.
After a few days of research i still got no clue how to perform this exactly. I have following worklfow in my head:
generate mesh with photogrammetry approach
create binary mask for specific image (most middle one)
convert mesh to 3d array (if possible?)
do array operation and combine 2d array (binary mask) with 3d array and set all values in 3d array to 0 that are not in my ROI
create mesh out of new 3D array
I'm still not sure if this could work. Is there any standard python approach to this?
I appreciate your time.
Related
I have skeletonized 2D and 3D images as follows:
2D skeleton
3D skeleton
Now, I want to analyze the skeletons in python and obtain the following information:
The location of nodes.
The adjacency list.
The connectivity (the number of continuous skeletons in an image).
Is there any approach to do this in python?
I`ve downloaded a sample .stl file from here: [https://www.thingiverse.com/thing:156207]
Then I've used this code to get a numpy array for further image processing with matplotlib:
import numpy as np
from stl import mesh
np.set_printoptions(threshold=np.nan)
# Using an existing stl file:
your_mesh = mesh.Mesh.from_file('300_polygon_sphere_100mm.stl')
data = np.array(your_mesh)
print(data.shape)
Unfortunately, this is an array with only two dimensions. I've checked the .stl file with my editor and there are three dimensions.
Can someone help me? My goal is to create a code with that i can slice 3D models to get acces to the sliced 2d images.
Thanks.
EDIT: I've tried to reshape it:
data_reshaped = np.reshape(data, (550, 3, 3))
But i guess this totally wrong. And i don't know if the pattern is (Z, X, Y).
I want to do some slicing operations on the 3d array to get XY images like this guy is very easily doing https://www.youtube.com/watch?v=5jQVQE6yfio&list=PLT66ZlnovHPYzny9TYM1mx02k5Xnw_kjw&t=215s&index=3
You won't be able to just load the .stl file into a numpy array and perform slicing as shown in the video you linked. In the video, they load a model that is stored as a 3D numpy array.
However, the model you are trying to load consists of a polygonal mesh. This means you only have the coordinate values of the vertices. You can open the .stl file in a text editor to see its contents. (By converting the loaded mesh into a numpy array you just extract those coordinate values. You can actually compare the values in the numpy array and the text file, they are the same.) The resulting numpy array has shape (550, 9). The first dimension is defined by the number of faces in the model (in this case, the model has 550 faces). As each face has three vertices, which have three coordinate values each, hence you have 9 numbers per face. So the third dimension is not lost. It's just stored in a different manner.
Simply reshaping the array won't create you a model of which you can get slices of, as shown in the video. To achieve this, you have to convert the meshed model into a rasterized one. You could do this by initializing an empty 3D array that contains the whole model and then determining for each pixel if it intersects with the geometry of the mesh you loaded.
I'm trying to implement a blob detector based on LOG, the steps are:
creating an array of n levels of LOG filters
use each of the filters on the input image to create a 3d array of h*w*n where h = height, w = width and n = number of levels.
find a local maxima and circle the blob in the original image.
I already created the filters and the 3d array (which is an array of 2d images).
I used padding to make sure I don't have any problems around the borders (which includes creating a constant border for each image and create 2 extra empty images).
Now I'm trying to figure out how to find the local maxima in the array.
I need to compare each pixel to its 26 neighbours (8 in the same picture and the 9 pixels in each of the two adjacent scales)
The brute force way of checking the pixel value directly seems ugly and not very efficient.
Whats the best way to find a local maxima point in python using openCV?
I'd take advantage of the fact that dilations are efficiently implemented in OpenCV. If a point is a local maximum in 3d, then it is also in any 2d slice, therefore:
Dilate each image in the array with a 3x3 kernel, keep as candidate maxima the points whose intensity is unchanged.
Brute-force test the candidates against their upper and lower slices.
Recently I did my own 2d-fft to get the frequency spectrum from 512x512 image, using python. I did the 2d-fft using 1d-fft, by doing the 1d on every row, and then on every column I ended up having a 512x512 matrix of complex numbers.
I want to know how can I construct the resulting image from this complex array? Should I use the real values only? Or should I convert the real and imaginary to magnitude and phase, and then use the magnitude to build up my resulting image?
I would like to display a satellite image (preferably using python, but other solutions are welcome). It consists in a floating-point parameter P, with dimension NxM, and each pixel is geolocated by the fields latitude and longitude (each of size NxM). So I would like to:
(1) create an image of parameter P with an associated color scale. The image should not be resampled, so it should have dimension NxM
(2) display coastlines over this image
Currently, I can do (1) using PIL. I can also use the basemap library to display an image and the coastlines, but I don't know how to do it without reprojection, by staying in the image native projection with size NxM.
Edit: the parameter P does not contain any information about the coastline. Only the location (lat, lon) of the pixels should be used to overlay the coastline. The coordinates for the coastline can be obtained from gshhs for example. gshhs is actually used in the basemap library.
If all you're trying to do is enhance the boundaries between land and water, it might be good to use a high-pass filter.
For instance, start out with Lena:
and apply a highpass filter:
then overlay the highpass on top of the original:
(more details and examples can be found here).
You can find filters in scipy here.
For those in the community still looking for an answer to this question, the method which I am currently implementing (for v. similar purposes - I'm trying to test the geolocation of satellite data) requires a landmask.
There are landmask datasets available all over the place online, each with different rules and characteristics. I am working with netCDF4 data in python and my landmask is a gridded .nc dataset in which ocean elements are valued as 1 and land elements are valued as 0.
Iterating through my satellite data I multiply each latitude and longitude value by the number of elements per degree in the landmask. In my case there are 120 elements per degree in lat/lon, so
lon_inds = (lons*120).astype(int)
lat_inds = (lats*120).astype(int)
A more general way of writing this would involve substituting 120 for
len(lons)/360
len(lats)/180
respectively. Both examples of these operations can be done nearly instantaneously if using numpy arrays (which is the case for the python netCDF4 module).
Now I create a mask of my own: it must have the same dimensions as the data array (for those not intimately acquainted with satellites, the data, lats and lons arrays will all have identical dimensions):
my_mask = np.zeros(data.shape, dtype=int)
Now all we need to do is replace values in the mask where there is a coastline. This is done by iterating through the lat_inds and lon_inds arrays, looking up the value in the landmask of
landmask[lon_inds[i,j],lat_inds[i,j]]
and changing the value of
mask[i,j]
to 1 if any of the neighbors
landmask[lon_inds[i,j]-1,lat_inds[i,j]]
landmask[lon_inds[i,j]+1,lat_inds[i,j]]
landmask[lon_inds[i,j],lat_inds[i,j]-1]
landmask[lon_inds[i,j],lat_inds[i,j]+1]
are not equal to 0 (of course, a smoother coastline can be generated by adding in the diagonal neighboring cells, but this should not be necessary as hopefully you should be using a landmask dataset with sharper spatial resolution than your satellite data).