vusr commited on
Commit
65cef96
·
verified ·
1 Parent(s): cf41815

Upload 2 files

Browse files
Files changed (2) hide show
  1. Image_height.py +74 -0
  2. Image_stitching.py +94 -0
Image_height.py ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from plantcv import plantcv as pcv
2
+ from PIL import Image
3
+ import glob
4
+ import matplotlib.pyplot as plt
5
+ import os
6
+ import numpy as np
7
+ import pandas as pd
8
+ from sklearn.decomposition import PCA
9
+ from skimage.filters import threshold_li
10
+
11
+
12
+ class options:
13
+ def __init__(self, image_path):
14
+ self.image = image_path
15
+ self.debug = "plot"
16
+ self.tmp_dir = "plantpattern"
17
+ self.result = os.path.join(self.tmp_dir, "try2.txt")
18
+ self.writeimg = False
19
+ self.outdir = "plantpattern"
20
+ os.makedirs(self.tmp_dir, exist_ok=True)
21
+
22
+ def image_height(image_path, camera_distance):
23
+ # Get options
24
+ args = options(image_path)
25
+
26
+ # Set debug to the global parameter
27
+ pcv.params.debug = args.debug
28
+
29
+ # Read image
30
+
31
+ # Inputs:
32
+ # filename - Image file to be read in
33
+ # mode - How to read in the image; either 'native' (default), 'rgb', 'gray', or 'csv'
34
+ original_img, path, filename = pcv.readimage(filename=args.image)
35
+
36
+ gray = pcv.rgb2gray(rgb_img=original_img)
37
+ thresh = threshold_li(gray)
38
+ binary = gray > thresh
39
+
40
+ s_thresh = binary.astype(int)
41
+ bs = pcv.logical_or(bin_img1=gray, bin_img2=np.uint8(s_thresh*255))
42
+ masked = pcv.apply_mask(img=original_img, mask=bs, mask_color='black')
43
+ ab_fill = pcv.fill(bin_img=s_thresh, size=10)
44
+ masked2 = pcv.apply_mask(img=masked, mask=ab_fill, mask_color='black')
45
+ id_objects, obj_hierarchy = pcv.find_objects(img=np.uint8(original_img*255), mask=ab_fill)
46
+ roi1, roi_hierarchy= pcv.roi.rectangle(img=masked2, x=95, y=5, h=500, w=350)
47
+ roi_objects, hierarchy3, kept_mask, obj_area = pcv.roi_objects(img=original_img, roi_contour=roi1,
48
+ roi_hierarchy=roi_hierarchy,
49
+ object_contour=id_objects,
50
+ obj_hierarchy=obj_hierarchy,
51
+ roi_type='partial')
52
+
53
+ obj, mask = pcv.object_composition(img=original_img, contours=roi_objects, hierarchy=hierarchy3)
54
+ analysis_image = pcv.analyze_object(img=original_img, obj=obj, mask=mask, label="default")
55
+ boundary_image2 = pcv.analyze_bound_horizontal(img=np.uint8(original_img*255), obj=obj, mask=mask,
56
+ line_position=510, label="default")
57
+ height_above_reference = pcv.outputs.observations['default']['height_above_reference']['value']
58
+ #small greenhouse distance = 30cm
59
+ #56.3 * 56.3
60
+ image_width, image_height, h = original_img.shape
61
+ x_offset = 56.3/512
62
+ actual_greenhouse_height = x_offset * height_above_reference
63
+ # print("Actual Height of plant:", actual_greenhouse_height)
64
+ # Create a DataFrame with the actual height
65
+ data = {'Parameter': ['Height Above Reference (pixels)', 'Plant height (cm)', 'Image Width (pixels)', 'Pixel Size (cm)'],
66
+ 'Value': [height_above_reference, actual_greenhouse_height, image_width, x_offset]}
67
+ df = pd.DataFrame(data)
68
+
69
+ return df, actual_greenhouse_height
70
+
71
+
72
+
73
+
74
+
Image_stitching.py ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import cv2
2
+ import numpy as np
3
+ import matplotlib.pyplot as plt
4
+ import pdb
5
+
6
+ def rotate_to_horizontal(image):
7
+ # Rotate the image to horizontal (90 degrees counterclockwise)
8
+ rotated_image = cv2.rotate(image, cv2.ROTATE_90_COUNTERCLOCKWISE)
9
+ return rotated_image
10
+
11
+ def rotate_to_vertical(image):
12
+ # Rotate the image back to vertical (90 degrees clockwise)
13
+ rotated_image = cv2.rotate(image, cv2.ROTATE_90_CLOCKWISE)
14
+ return rotated_image
15
+
16
+ def plot_images(images):
17
+ num_images = len(images)
18
+
19
+ for i, image in enumerate(images):
20
+ plt.figure(figsize=(6, 6))
21
+ plt.imshow(image)
22
+ plt.title(f"Image {i+1}/{num_images}")
23
+ plt.axis('off')
24
+ plt.show()
25
+
26
+ def image_stitching(images):
27
+ # images = [cv2.imread(path) for path in image_paths]
28
+
29
+ images = [image.astype(np.uint8) for image in images]
30
+ images = [rotate_to_horizontal(image) for image in images]
31
+ images = list(reversed(images))
32
+ if len(images) == 15:
33
+ images = images[2:12]
34
+ #plot_images(images)
35
+
36
+ # Create a list to store the stitched images
37
+ stitched_images = []
38
+
39
+ # Accumulated homography matrix for stitching
40
+ accumulated_homography = np.eye(3)
41
+
42
+ # Iterate through pairs of adjacent images and stitch them together
43
+ for i in range(len(images) - 1):
44
+ # Perform keypoint and feature descriptor extraction
45
+ orb = cv2.ORB_create()
46
+ keypoints_and_descriptors = [orb.detectAndCompute(image, None) for image in [images[i], images[i + 1]]]
47
+
48
+ # Match the keypoints using Brute-Force Matcher
49
+ bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
50
+ matches = bf.match(keypoints_and_descriptors[0][1], keypoints_and_descriptors[1][1])
51
+
52
+ # Filter the matches to remove outliers using RANSAC
53
+ src_pts = np.float32([keypoints_and_descriptors[0][0][m.queryIdx].pt for m in matches]).reshape(-1, 1, 2)
54
+ dst_pts = np.float32([keypoints_and_descriptors[1][0][m.trainIdx].pt for m in matches]).reshape(-1, 1, 2)
55
+
56
+ M, _ = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0)
57
+
58
+ # Accumulate the homography matrices
59
+ accumulated_homography = np.dot(M, accumulated_homography)
60
+
61
+ # Warp perspective and stitch the images
62
+ stitched_image = cv2.warpPerspective(images[i + 1], accumulated_homography,
63
+ (images[i].shape[1] + images[i + 1].shape[1], images[i].shape[0]))
64
+ stitched_image[0:images[i].shape[0], 0:images[i].shape[1]] = images[i]
65
+
66
+ # Remove the empty pixels and retain maximum image information
67
+ # stitched_image = remove_empty_pixels(stitched_image)
68
+
69
+ stitched_images.append(stitched_image)
70
+
71
+ # Combine all stitched images into a final panorama
72
+ final_panorama = stitched_images[0]
73
+ for i in range(1, len(stitched_images)):
74
+ final_panorama = cv2.warpPerspective(stitched_images[i], np.eye(3),
75
+ (final_panorama.shape[1] + stitched_images[i].shape[1], final_panorama.shape[0]))
76
+ final_panorama[0:stitched_images[i].shape[0], 0:stitched_images[i].shape[1]] = stitched_images[i]
77
+
78
+ gray_images = [cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) for image in images[:2]]
79
+
80
+ # Draw the keypoints on the images
81
+ keypoints_drawn = [cv2.drawKeypoints(gray_image, kp[0], None, color=(0, 255, 0),
82
+ flags=cv2.DrawMatchesFlags_DRAW_RICH_KEYPOINTS) for gray_image, kp in
83
+ zip(gray_images, keypoints_and_descriptors[:2])]
84
+
85
+ # Draw the matches on the images
86
+ matches_drawn = cv2.drawMatches(images[0], keypoints_and_descriptors[0][0], images[1],
87
+ keypoints_and_descriptors[1][0], matches, None, flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)
88
+
89
+ # Crop the final image to 512x512 centered around the middle
90
+ cropped_final_panorama = final_panorama[:512, :512]
91
+ rotated_final_panorama = rotate_to_vertical(cropped_final_panorama)
92
+
93
+
94
+ return rotated_final_panorama