Commit b5741f3b authored by luroth's avatar luroth
Browse files

Input Ear segmentation Simon Treier

parent abab4a51
......@@ -16,11 +16,16 @@ from skimage.morphology import watershed
from scipy.ndimage.measurements import center_of_mass, label
from scipy.sparse import csr_matrix
from pathlib import Path
from matplotlib import path as geopath
import cv2
from progressbar import ProgressBar
import multiprocessing
from multiprocessing import Process, Manager
from Common import MaskRead
def segment_ear_image(path_raw, path_processed, raw_image_name,
GSD = 3.02, # Indicate ground sampling distance in mm
......@@ -196,3 +201,172 @@ def segment_ear_images_process(path_raw_files, output_directory,
for p in processes:
p.join()
def process_multiview_earcount_generation(path_processed_str, design_label, nx=50 * 20, ny=125, buffer=0, subplots=False,
rmdest=False):
print("Processing design", design_label)
path_processed = Path(path_processed_str)
path_seg_ear = path_processed / 'ear_count'
path_masks = path_processed / 'image_masks'
path_mvEars = path_processed / 'mvEar'
if rmdest:
try:
shutil.rmtree(path_mvEars, ignore_errors=True)
except:
print("Could not remove ", path_mvEars)
path_mvEars.mkdir(exist_ok=True)
# Read all masks
gpd_masks = MaskRead.read_masks(path_masks, design_label)
gpd_masks['geometry'] = gpd_masks.buffer(buffer)
# Generate sample matrix and coords
vx, vy = np.mgrid[0:nx, 0:ny]
samplepoints_array = np.zeros((nx, ny))
samplepoints_coords = np.stack((vx.flatten(), vy.flatten()), axis=1)
samplepoints_normalized_coords = samplepoints_coords / (nx - 1, ny - 1)
# Split plot label in group and subnumber
if subplots:
gpd_masks['plot_group'] = gpd_masks.plot_label.str[0:11]
gpd_masks['plot_subnumber'] = np.int8(gpd_masks.plot_label.str[12:])
# Dicts to store sample ground coverage / aerial coverage arrays in
ear_counts = []
plot_resamples = {}
plot_image_count = {}
plot_labels = np.unique(gpd_masks['plot_label'])
for plot_label in plot_labels:
plot_resamples[plot_label] = samplepoints_array.copy().flatten()
plot_image_count[plot_label] = 0
# Process image by image
image_groups = gpd_masks.groupby("image")
for image, image_group in image_groups:
print(f'Process {image}')
# Load segmented image
path_image = path_seg_ear / (image + '_watershed.tif')
if path_image.exists():
image_segmented = imageio.imread(path_image)
ear_count_coords = np.array(pd.read_csv(path_seg_ear / (image + '_localmax.csv')), dtype=np.uint16)
# Convert to to [0, 1]
image_segmented_filtered = image_segmented
image_segmented_filtered[image_segmented_filtered > 0] = 1
# Process plots on image
plot_label_groups = image_group.groupby("plot_label")
for plot_label, plot_label_group in plot_label_groups:
# Process different shapes
for _, plot in plot_label_group.iterrows():
if plot['type'] == 'canopy':
# Get postion of plot edges on image
plot_polygon = plot.at['geometry']
x, y = plot_polygon.exterior.coords.xy
plot_edges_image_coords = np.float32(np.stack([x, y], axis=1))
# Get affine transform matrix to transform from 0:1, 0:1 space to image coords
plot_edges_normalized_coords = np.float32([[0, 0], [0, 1], [1, 1], [1, 0]])
M_normalized_to_image_coords = cv2.getAffineTransform(plot_edges_normalized_coords[0:3, :],
plot_edges_image_coords[0:3, :])
# Get position of plot raster points on image
samplepoints_image_coords = np.int16(
np.round(np.dot(
np.c_[samplepoints_normalized_coords, np.ones(samplepoints_normalized_coords.shape[0])],
M_normalized_to_image_coords.T)))
# Filter border pixels
border = 100
is_border = np.any(samplepoints_image_coords[:, 1] > image_segmented.shape[0] - 1 - border) or \
np.any(samplepoints_image_coords[:, 1] < 0 + border) or \
np.any(samplepoints_image_coords[:, 0] > image_segmented.shape[1] - 1 - border) or \
np.any(samplepoints_image_coords[:, 0] < 0 + border)
if not is_border:
# Sample oblique segmented image with samplepoints
sampled = image_segmented_filtered[
samplepoints_image_coords[:, 1], samplepoints_image_coords[:, 0]]
##DEBUG
'''
plt.figure()
plt.imshow(image_segmented_filtered)
plt.scatter(samplepoints_image_coords[:, 0], samplepoints_image_coords[:, 1])
plt.scatter(samplepoints_image_coords[50, 0], samplepoints_image_coords[50, 1])
plt.scatter(samplepoints_image_coords[100, 0], samplepoints_image_coords[100, 1])
plt.scatter(samplepoints_image_coords[200, 0], samplepoints_image_coords[200, 1])
plt.scatter(samplepoints_image_coords[600, 0], samplepoints_image_coords[600, 1])
plt.scatter(samplepoints_image_coords[125:250, 0], samplepoints_image_coords[125:250, 1])
plt.scatter(samplepoints_image_coords[1000:1125, 0], samplepoints_image_coords[1000:1125, 1])
plt.show()
plt.figure()
sampled_img = sampled.reshape((50, 125))
plt.imshow(sampled_img.T)
plt.show()
'''
plot_resamples[plot_label] += sampled
plot_image_count[plot_label] += 1
# Sample plot polygon for ear counts
# Transform coordinates to path
sample_path = geopath.Path(plot_edges_image_coords)
# Sample ears
ears_in_poly = sample_path.contains_points(ear_count_coords, radius=abs(1))
ear_counts_ = np.sum(ears_in_poly*1)
plot['ear_count'] = ear_counts_
del (plot['geometry'])
ear_counts.append(plot.to_dict())
# Normalize GC_ACs with image counts
for plot_label in plot_resamples.keys():
plot_resamples[plot_label] /= plot_image_count[plot_label]
# Save to disk
try:
path_mvEars.mkdir()
except:
pass
if subplots:
plot_groups = np.unique(gpd_masks['plot_group'])
for plot_group in plot_groups:
print(f"Summarizing {plot_group} with subplots")
plots = []
for i in range(20):
plot_label = plot_group + "_" + str(i + 1)
plot = plot_resamples[plot_label].reshape(samplepoints_array.shape[0], samplepoints_array.shape[1])
plot = np.uint8(plot * 255).T
imageio.imsave(str(path_mvEars / (design_label + "_" + plot_label + ".tif")), plot)
plots.append(plot)
all_plots = np.concatenate(plots, axis=1)
imageio.imsave(str(path_mvEars / (design_label + "_" + plot_group + ".tif")), all_plots)
else:
plot_labels = np.unique(gpd_masks['plot_label'])
for plot_label in plot_labels:
print(f"Summarizing {plot_label}")
plot = plot_resamples[plot_label].reshape(samplepoints_array.shape)
plot = np.uint8(plot * 255).T
imageio.imsave(str(path_mvEars / (design_label + "_" + plot_label + ".tif")), plot)
# Save canopy coverages
df_ear_counts = pd.DataFrame(ear_counts)
df_ear_counts.to_csv(str(path_mvEars / (design_label + "_" + "ear_counts.csv")), index=False)
\ No newline at end of file
......@@ -14,7 +14,7 @@ from scipy.optimize import curve_fit
from sklearn.metrics import mean_squared_error
from math import sqrt
from GroundAerialCoverage import MaskRead
from Common import MaskRead
def P_p_from_CC_LC(view, CC, LC, c_1=0, c_2=0):
......
from EarCount import EarCountProcessing
from pathlib import Path
if __name__ == "__main__":
dates = [
'20190605']
for date in dates:
print("process", date)
# Paths
path_processed = Path(r'O:\UAV\_Processed_\ETHZ_eschikon_FPWW024_lot4') / date / '28m_M600P'
path_processed = Path(r'/home/luroth/public/Evaluation/UAV/_Processed_/ETHZ_eschikon_FPWW024_lot4') / date / '28m_M600P'
# Others
design_labels = ['FPWW024_lot4']
for design_label in design_labels:
# input GSD and buffer
GSD = 0.003 # m
buffer = round(-0.3 / GSD) # 0.3 m buffer
# output image size
GSD_output = 0.001 # m
ny, nx = (round( (5.5 - (2 * 0.3) ) / GSD_output), round( ( 1.5 - (2 * 0.3) ) / GSD_output) )
EarCountProcessing.process_multiview_earcount_generation(path_processed, design_label, nx=nx, ny=ny , subplots=None, buffer=buffer)
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment