(
vector_field: np.ndarray,
mask: np.ndarray,
target_iteration_count: int,
thread_count: int,
)
| 111 | |
| 112 | |
| 113 | def integrate_vector_field( |
| 114 | vector_field: np.ndarray, |
| 115 | mask: np.ndarray, |
| 116 | target_iteration_count: int, |
| 117 | thread_count: int, |
| 118 | ) -> np.ndarray: |
| 119 | shape = vector_field.shape[:2] |
| 120 | angles = np.linspace(0, 90, target_iteration_count, endpoint=False) |
| 121 | |
| 122 | def integrate_vector_field_angles(angles: List[float]) -> np.ndarray: |
| 123 | all_combined_heights = np.zeros(shape) |
| 124 | |
| 125 | for angle in angles: |
| 126 | rotated_vector_field = rotate_vector_field_normals( |
| 127 | rotate(vector_field, angle), angle |
| 128 | ) |
| 129 | rotated_mask = rotate(mask, angle) |
| 130 | |
| 131 | left_gradients, top_gradients = calculate_gradients( |
| 132 | rotated_vector_field, rotated_mask |
| 133 | ) |
| 134 | ( |
| 135 | left_heights, |
| 136 | right_heights, |
| 137 | top_heights, |
| 138 | bottom_heights, |
| 139 | ) = calculate_heights(left_gradients, top_gradients, rotated_mask) |
| 140 | |
| 141 | combined_heights = combine_heights( |
| 142 | left_heights, right_heights, top_heights, bottom_heights |
| 143 | ) |
| 144 | combined_heights = centered_crop(rotate(combined_heights, -angle), shape) |
| 145 | all_combined_heights += combined_heights / len(angles) |
| 146 | |
| 147 | return all_combined_heights |
| 148 | |
| 149 | with Pool(processes=thread_count) as pool: |
| 150 | heights = pool.map( |
| 151 | integrate_vector_field_angles, |
| 152 | np.array( |
| 153 | np.array_split(angles, thread_count), |
| 154 | dtype=object, |
| 155 | ), |
| 156 | ) |
| 157 | pool.close() |
| 158 | pool.join() |
| 159 | |
| 160 | isotropic_height = np.zeros(shape) |
| 161 | for height in heights: |
| 162 | isotropic_height += height / thread_count |
| 163 | |
| 164 | return isotropic_height |
| 165 | |
| 166 | |
| 167 | def estimate_height_map( |
no outgoing calls
no test coverage detected