D. Colorful Points

本文介绍了一道关于颜色点删除的模拟题,通过算法实现对直线上一系列带有颜色标记的点进行操作,直到无法继续删除。文章详细解释了算法流程,并提供了完整的代码示例。
D. Colorful Points
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

You are given a set of points on a straight line. Each point has a color assigned to it. For point a, its neighbors are the points which don't have any other points between them and a. Each point has at most two neighbors - one from the left and one from the right.

You perform a sequence of operations on this set of points. In one operation, you delete all points which have a neighbor point of a different color than the point itself. Points are deleted simultaneously, i.e. first you decide which points have to be deleted and then delete them. After that you can perform the next operation etc. If an operation would not delete any points, you can't perform it.

How many operations will you need to perform until the next operation does not have any points to delete?

Input

Input contains a single string of lowercase English letters 'a'-'z'. The letters give the points' colors in the order in which they are arranged on the line: the first letter gives the color of the leftmost point, the second gives the color of the second point from the left etc.

The number of the points is between 1 and 106.

Output

Output one line containing an integer - the number of operations which can be performed on the given set of points until there are no more points to delete.

Examples
input
Copy
aabb
output
Copy
2
input
Copy
aabcaa
output
Copy
1
Note

In the first test case, the first operation will delete two middle points and leave points "ab", which will be deleted with the second operation. There will be no points left to apply the third operation to.

In the second test case, the first operation will delete the four points in the middle, leaving points "aa". None of them have neighbors of other colors, so the second operation can't be applied.


模拟题,我们可以发现第一遍删除后字符串相同的部分会在一起,然后我们把字符串分成多个部分,每个部分由相同的字符组成,中间的部分每次删除的时候减二,两端删除的时候减一,关键一点是合并,在每次删除过后要合并掉相同的部分,这步可能会忘记

#include <bits/stdc++.h>

using namespace  std;

const int inf = 1e6 + 10;
struct{
    char id;
    int shu;
}num[inf], num2[inf];
int main()
{
    string a, b;
    cin >> a;
    bool fou = true;
    int ans = 0;
        b = "";
        int len = a.length();
        for(int i = 0; i < len; i ++){
            fou = true;
             if(i + 1 < len){
                if(a[i + 1] != a[i]){
                    fou = false;
                }
             }
             if(i - 1 >= 0){
                if(a[i - 1] != a[i]) {
                    fou = false;
                }
             }
             if(fou){
                b += a[i];
             }
        }
        if(a == b){
           ans = 0;
        }else {
            ans = 1;
            int len1 = 0;
            len = b.length();
            num[0].shu = 1;
            num[0].id = b[0];
            for(int i = 1; i < len;i ++){
                if(b[i] == b[i - 1]){
                    num[len1].shu ++;
                    num[len1].id = b[i];
                }else {
                    num[++ len1].shu = 1;
                    num[len1].id = b[i];
                }
            }
            len1 ++;//表明有len1个部分
            while(len1 > 1){
                len = len1;
                len1 = 0;
                for(int i = 1; i < len - 1; i ++){
                    num[i].shu -= 2;
                }
                num[0].shu --;
                num[len - 1].shu --;
                for(int i = 0;i < len; i ++){
                    if(num[i].shu > 0){
                        num[len1 ++] = num[i];
                    }
                }
                len = 0;
                num2[0] = num[0];
                for(int i = 1; i < len1; i ++){
                    if(num[i].id == num2[len].id){
                        num2[len].shu += num[i].shu;
                    }else {
                        num2[++ len] = num[i];
                    }
                }
                ans ++;
                for(int i = 0; i <= len; i ++){
                    num[i] = num2[i];
                }
                len1 = len;
                len1 ++;
            }
        }
        cout << ans << endl;
    return 0;
}

我需要 彩色的,点云重建得好的。代码:import os import cv2 import numpy as np import matplotlib.pyplot as plt import argparse import trimesh from tqdm import tqdm from typing import Tuple import time def normalize_disparity_map(disparity_map): """Normalize disparity map for visualization, clip negative values.""" disparity_valid = disparity_map[disparity_map > 0] if len(disparity_valid) == 0: return np.zeros_like(disparity_map) d_min, d_max = disparity_valid.min(), disparity_valid.max() normalized = np.zeros_like(disparity_map, dtype=np.float32) if d_max > d_min: normalized = (disparity_map - d_min) / (d_max - d_min) normalized[disparity_map <= 0] = 0 return normalized def visualize_disparity_map(disparity_map, gt_map, save_path=None): """ Visualize or save the estimated and ground truth disparity maps side-by-side. Use JET colormap for better visual interpretation (colorful). """ # Normalize both maps disp_norm = normalize_disparity_map(disparity_map) gt_norm = normalize_disparity_map(gt_map) # Apply jet colormap -> (H, W, 3) disp_color = plt.cm.jet(disp_norm)[:, :, :3] # Remove alpha gt_color = plt.cm.jet(gt_norm)[:, :, :3] # Concatenate horizontally: [result | GT] concat_color = np.hstack([disp_color, gt_color]) if save_path is None: plt.figure(figsize=(12, 5)) plt.imshow(concat_color) plt.axis('off') plt.title("Estimated Disparity (left) vs Ground Truth (right)") plt.show() else: os.makedirs(os.path.dirname(save_path), exist_ok=True) plt.imsave(save_path, concat_color, cmap='jet') # Save as colorful PNG print(f"Disparity map saved to {save_path}") def task1_compute_disparity_map_simple( ref_img: np.ndarray, sec_img: np.ndarray, window_size: int, disparity_range: Tuple[int, int], matching_function: str ): """ Compute disparity map using simple window-based matching. Uses OpenCV's boxFilter for fast cost aggregation. Returns a single-channel float32 disparity map. """ ref = ref_img.astype(np.float32) sec = sec_img.astype(np.float32) H, W = ref.shape dmin, dmax = disparity_range if dmin < 0: raise ValueError("min_disparity should be >= 0.") disparities = list(range(dmin, dmax + 1)) ksize = (window_size, window_size) N = float(window_size * window_size) eps = 1e-6 cost_volume = np.empty((len(disparities), H, W), dtype=np.float32) for idx, d in enumerate(disparities): shifted_sec = np.zeros_like(sec) if d == 0: shifted_sec = sec.copy() else: shifted_sec[:, d:] = sec[:, :-d] if matching_function == "SSD": diff = ref - shifted_sec cost = cv2.boxFilter(diff * diff, -1, ksize, normalize=False, borderType=cv2.BORDER_REFLECT101) elif matching_function == "SAD": diff = np.abs(ref - shifted_sec) cost = cv2.boxFilter(diff, -1, ksize, normalize=False, borderType=cv2.BORDER_REFLECT101) elif matching_function == "normalized_correlation": sumI = cv2.boxFilter(ref, -1, ksize, normalize=False, borderType=cv2.BORDER_REFLECT101) sumJ = cv2.boxFilter(shifted_sec, -1, ksize, normalize=False, borderType=cv2.BORDER_REFLECT101) sumI2 = cv2.boxFilter(ref * ref, -1, ksize, normalize=False, borderType=cv2.BORDER_REFLECT101) sumJ2 = cv2.boxFilter(shifted_sec * shifted_sec, -1, ksize, normalize=False, borderType=cv2.BORDER_REFLECT101) sumIJ = cv2.boxFilter(ref * shifted_sec, -1, ksize, normalize=False, borderType=cv2.BORDER_REFLECT101) num = sumIJ - (sumI * sumJ) / N den = np.sqrt(np.maximum(sumI2 - sumI*sumI/N, 0)) * np.sqrt(np.maximum(sumJ2 - sumJ*sumJ/N, 0)) + eps ncc = num / den cost = -ncc # Maximize NCC => Minimize (-NCC) else: raise ValueError(f"Unknown matching function: {matching_function}") if d > 0: cost[:, :d] = np.inf cost_volume[idx] = cost best_idx = np.argmin(cost_volume, axis=0) disparity_map = np.take(np.array(disparities, dtype=np.float32), best_idx) best_cost = np.min(cost_volume, axis=0) disparity_map[~np.isfinite(best_cost)] = 0.0 return disparity_map def task1_simple_disparity(ref_img, sec_img, gt_map, img_name='tsukuba'): """ Run Task 1: test different configurations of window size, disparity range, and matching function. Save all results as colorful disparity images and log runtime. """ window_sizes = [5, 9, 15] disparity_range = (0, 64) matching_functions = ['SSD', 'SAD', 'normalized_correlation'] disparity_maps = [] print(f"🚀 Starting Task 1: Testing multiple configurations on '{img_name}'...") for window_size in window_sizes: for matching_function in matching_functions: start_time = time.time() print(f"⚙️ Computing: ws={window_size}, func={matching_function}") disparity_map = task1_compute_disparity_map_simple( ref_img, sec_img, window_size, disparity_range, matching_function) runtime = time.time() - start_time print(f"⏱️ Done in {runtime:.2f}s") disparity_maps.append((disparity_map.copy(), window_size, matching_function, disparity_range)) # Save path with full info dmin, dmax = disparity_range save_path = f"output/task1_{img_name}_{window_size}_{dmin}_{dmax}_{matching_function}.png" visualize_disparity_map(disparity_map, gt_map, save_path=save_path) # Log runtime for report with open("output/runtime_log.txt", "a") as f: f.write(f"Task1,{img_name},{window_size},{dmin},{dmax},{matching_function},{runtime:.4f}\n") return disparity_maps def task2_compute_depth_map(disparity_map, baseline=0.2, focal_length=615): """ Convert disparity to depth using z = fB / d Ignore zero/negative disparities. """ depth_map = np.zeros_like(disparity_map, dtype=np.float32) valid = disparity_map > 0 depth_map[valid] = (focal_length * baseline) / (disparity_map[valid] + 1e-8) return depth_map def task2_visualize_pointcloud( ref_img_bgr: np.ndarray, disparity_map: np.ndarray, save_path: str = 'output/task2_tsukuba.ply' ): """ Generate a FULLY COLORFUL 3D point cloud from disparity. - X,Y: pixel coordinates - Z: depth derived from disparity - Color: true RGB from reference image (convert BGR → RGB) Filters out invalid depths and extreme outliers. """ # Calibration parameters (Tsukuba dataset typical values) baseline = 0.2 # meters focal_length = 615 # pixels depth_map = task2_compute_depth_map(disparity_map, baseline, focal_length) # Remove infinite/nan and clip top 1% valid = np.isfinite(depth_map) & (depth_map > 0) if np.sum(valid) == 0: print("⚠️ No valid depth points found!") return # Clip far outliers max_depth = np.percentile(depth_map[valid], 99) valid &= (depth_map <= max_depth) H, W = depth_map.shape xs, ys = np.meshgrid(np.arange(W), np.arange(H), indexing='xy') points = np.stack([xs[valid], ys[valid], depth_map[valid]], axis=1) # Convert BGR to RGB and extract colors ref_rgb = cv2.cvtColor(ref_img_bgr, cv2.COLOR_BGR2RGB) colors = ref_rgb[valid].reshape(-1, 3).astype(np.uint8) # Create and save PLY pc = trimesh.PointCloud(vertices=points, colors=colors) os.makedirs(os.path.dirname(save_path), exist_ok=True) pc.export(save_path, file_type='ply') print(f"🎨 Colored point cloud saved to {save_path}") def task3_compute_disparity_map_dp(ref_img, sec_img): """ Dynamic Programming based stereo matching along horizontal scanlines. Handles occlusions via penalty terms. """ ref = ref_img.astype(np.float32) sec = sec_img.astype(np.float32) H, W = ref.shape occlusion_penalty = 20.0 max_disparity = 64 disparity_map = np.zeros((H, W), dtype=np.float32) t0 = time.perf_counter() for r in tqdm(range(H), desc="DP Scanline Processing"): L = ref[r] R = sec[r] dp = np.full((W+1, W+1), np.inf, dtype=np.float32) move = np.zeros((W+1, W+1), dtype=np.uint8) # 0=match, 1=occL, 2=occR dp[0, 0] = 0.0 for i in range(1, W+1): dp[i, 0] = dp[i-1, 0] + occlusion_penalty move[i, 0] = 1 for i in range(1, W+1): li = L[i-1] for j in range(1, i+1): # Match only if within max_disparity disp = i - j if disp <= max_disparity: c_match = dp[i-1, j-1] + abs(li - R[j-1]) else: c_match = np.inf c_occL = dp[i-1, j] + occlusion_penalty c_occR = dp[i, j-1] + occlusion_penalty if c_match <= c_occL and c_match <= c_occR: dp[i, j] = c_match move[i, j] = 0 elif c_occL <= c_occR: dp[i, j] = c_occL move[i, j] = 1 else: dp[i, j] = c_occR move[i, j] = 2 # Backtrack i, j = W, W while i > 0 or j > 0: m = move[i, j] if i > 0 and j > 0 and m == 0: disparity_map[r, i-1] = float(i - j) i -= 1 j -= 1 elif i > 0 and (j == 0 or m == 1): disparity_map[r, i-1] = 0.0 i -= 1 else: j -= 1 t1 = time.perf_counter() print(f"[Task3] DP runtime: {t1 - t0:.3f}s") return disparity_map def main(tasks): # Load images try: moebius_img1 = cv2.imread("data/moebius1.png") moebius_img1_gray = cv2.cvtColor(moebius_img1, cv2.COLOR_BGR2GRAY).astype(np.float32) moebius_img2 = cv2.imread("data/moebius2.png") moebius_img2_gray = cv2.cvtColor(moebius_img2, cv2.COLOR_BGR2GRAY).astype(np.float32) moebius_gt = cv2.imread("data/moebius_gt.png", cv2.IMREAD_GRAYSCALE).astype(np.float32) except Exception as e: print("Moebius data not available:", e) tsukuba_img1 = cv2.imread("data/tsukuba1.jpg") tsukuba_img1_gray = cv2.cvtColor(tsukuba_img1, cv2.COLOR_BGR2GRAY).astype(np.float32) tsukuba_img2 = cv2.imread("data/tsukuba2.jpg") tsukuba_img2_gray = cv2.cvtColor(tsukuba_img2, cv2.COLOR_BGR2GRAY).astype(np.float32) tsukuba_gt = cv2.imread("data/tsukuba_gt.jpg", cv2.IMREAD_GRAYSCALE).astype(np.float32) # Ensure output directory exists os.makedirs("output", exist_ok=True) # Clear or init runtime log with open("output/runtime_log.txt", "a") as f: f.write("Method,Image,WindowSize,dMin,dMax,MatchingFunction,Runtime(s)\n") # Task 0: OpenCV Baseline if '0' in tasks: print('🔧 Running Task 0: OpenCV StereoBM baseline...') stereo = cv2.StereoBM.create(numDisparities=64, blockSize=15) tsukuba_disparity_cv2 = stereo.compute(tsukuba_img1_gray.astype(np.uint8), tsukuba_img2_gray.astype(np.uint8)).astype(np.float32) tsukuba_disparity_cv2[tsukuba_disparity_cv2 < 0] = 0 visualize_disparity_map(tsukuba_disparity_cv2, tsukuba_gt, save_path="output/task0_tsukuba_colormap.png") if '2' in tasks: task2_visualize_pointcloud(tsukuba_img1, tsukuba_disparity_cv2, save_path='output/task2_tsukuba_cv2.ply') # Task 1: Simple Matching if '1' in tasks: print('🔍 Running Task 1: Window-based Matching with Multiple Settings...') start_time = time.time() disparity_maps = task1_simple_disparity(tsukuba_img1_gray, tsukuba_img2_gray, tsukuba_gt, img_name='tsukuba') total_time = time.time() - start_time print(f"🏁 Task 1 completed in {total_time:.2f}s") if '2' in tasks: print('🎨 Generating colored point clouds for each Task 1 result...') for dm, ws, mf, dr in disparity_maps: dmin, dmax = dr path = f'output/task2_tsukuba_{ws}_{dmin}_{dmax}_{mf}.ply' task2_visualize_pointcloud(tsukuba_img1, dm, save_path=path) # Task 3: DP Matching if '3' in tasks: print('⚡ Running Task 3: Dynamic Programming Matching...') start_time = time.time() tsukuba_disparity_dp = task3_compute_disparity_map_dp(tsukuba_img1_gray, tsukuba_img2_gray) runtime = time.time() - start_time print(f"⏱️ Task 3 runtime: {runtime:.2f}s") with open("output/runtime_log.txt", "a") as f: f.write(f"Task3,tsukuba,DP,0,64,DP,{runtime:.4f}\n") visualize_disparity_map(tsukuba_disparity_dp, tsukuba_gt, save_path='output/task3_tsukuba_colormap.png') if '2' in tasks: task2_visualize_pointcloud(tsukuba_img1, tsukuba_disparity_dp, save_path='output/task2_tsukuba_dp.ply') if __name__ == '__main__': parser = argparse.ArgumentParser(description='Homework 4: Binocular Stereo (FULL COLOR VERSION)') parser.add_argument('--tasks', type=str, default='0123', help='Tasks to run: e.g., 0, 12, 023') args = parser.parse_args() main(args.tasks) 。 严格按照题目要求,不要修改原代码
最新发布
11-28
import os import cv2 import numpy as np import matplotlib.pyplot as plt import argparse import trimesh import multiprocessing as mp from tqdm import tqdm from typing import Tuple import time def normalize_disparity_map(disparity_map): '''Normalize disparity map for visualization disparity should be larger than zero ''' return np.maximum(disparity_map, 0.0) / (disparity_map.max() + 1e-10) def visualize_disparity_map(disparity_map, gt_map, save_path=None): '''Visualize or save disparity map and compare with ground truth ''' # Normalize disparity maps disparity_map = normalize_disparity_map(disparity_map) gt_map = normalize_disparity_map(gt_map) # Visualize or save to file if save_path is None: concat_map = np.concatenate([disparity_map, gt_map], axis=1) plt.imshow(concat_map, 'gray') plt.show() else: os.makedirs(os.path.dirname(save_path), exist_ok=True) concat_map = np.concatenate([disparity_map, gt_map], axis=1) plt.imsave(save_path, concat_map, cmap='gray') def task1_compute_disparity_map_simple( ref_img: np.ndarray, # shape (H, W) sec_img: np.ndarray, # shape (H, W) window_size: int, disparity_range: Tuple[int, int], # (min_disparity, max_disparity) matching_function: str # can be 'SSD', 'SAD', 'normalized_correlation' ): '''Assume image planes are parallel to each other Compute disparity map using simple stereo system following the steps: 1. For each row, scan all pixels in that row 2. Generate a window for each pixel in ref_img 3. Search for a disparity (d) within (min_disparity, max_disparity) in sec_img 4. Select the best disparity that minimize window difference between ref_img[row, col] and sec_img[row, col - d] ''' ref = ref_img.astype(np.float32) sec = sec_img.astype(np.float32) H, W = ref.shape dmin, dmax = disparity_range if dmin < 0: raise ValueError("min_disparity should be >= 0 for rectified stereo pairs.") if dmax < dmin: raise ValueError("max_disparity should be >= min_disparity.") disparities = list(range(dmin, dmax + 1)) # Use fast box filter to aggregate window costs ksize = (int(window_size), int(window_size)) N = float(window_size * window_size) eps = 1e-6 cost_volume = np.empty((len(disparities), H, W), dtype=np.float32) if matching_function not in {"SSD", "SAD", "normalized_correlation"}: raise ValueError(f"Unknown matching function: {matching_function}") for idx, d in enumerate(disparities): # shifted_sec[:, col] = sec[:, col - d] (valid for col >= d) shifted_sec = np.zeros_like(sec) if d == 0: shifted_sec = sec else: shifted_sec[:, d:] = sec[:, :-d] if matching_function == "SSD": diff = (ref - shifted_sec) cost = cv2.boxFilter(diff * diff, ddepth=-1, ksize=ksize, normalize=False, borderType=cv2.BORDER_REFLECT101) elif matching_function == "SAD": diff = np.abs(ref - shifted_sec) cost = cv2.boxFilter(diff, ddepth=-1, ksize=ksize, normalize=False, borderType=cv2.BORDER_REFLECT101) else: # normalized_correlation # NCC = cov(I,J) / (std(I) std(J)) sumI = cv2.boxFilter(ref, -1, ksize, normalize=False, borderType=cv2.BORDER_REFLECT101) sumJ = cv2.boxFilter(shifted_sec, -1, ksize, normalize=False, borderType=cv2.BORDER_REFLECT101) sumI2 = cv2.boxFilter(ref * ref, -1, ksize, normalize=False, borderType=cv2.BORDER_REFLECT101) sumJ2 = cv2.boxFilter(shifted_sec * shifted_sec, -1, ksize, normalize=False, borderType=cv2.BORDER_REFLECT101) sumIJ = cv2.boxFilter(ref * shifted_sec, -1, ksize, normalize=False, borderType=cv2.BORDER_REFLECT101) num = sumIJ - (sumI * sumJ) / N den = np.sqrt(np.maximum(sumI2 - (sumI * sumI) / N, 0.0) * np.maximum(sumJ2 - (sumJ * sumJ) / N, 0.0)) + eps ncc = num / den cost = -ncc # maximize NCC == minimize (-NCC) # Mask invalid region where (col - d) < 0 if d > 0: cost[:, :d] = np.inf cost_volume[idx] = cost best_idx = np.argmin(cost_volume, axis=0) disparity_map = np.take(np.array(disparities, dtype=np.float32), best_idx) # If a pixel has no valid disparity (all inf), set to 0 best_cost = np.min(cost_volume, axis=0) disparity_map[~np.isfinite(best_cost)] = 0.0 return disparity_map def task1_simple_disparity(ref_img, sec_img, gt_map, img_name='tsukuba'): '''Compute disparity maps for different settings ''' window_sizes = [5, 9, 15] # Try different window sizes disparity_range = (0, 64) # Determine appropriate disparity range matching_functions = ['SSD', 'SAD', 'normalized_correlation'] # Try different matching functions disparity_maps = [] # Generate disparity maps for different settings for window_size in window_sizes: for matching_function in matching_functions: print(f"Computing disparity map for window_size={window_size}, disparity_range={disparity_range}, matching_function={matching_function}") disparity_map = task1_compute_disparity_map_simple( ref_img, sec_img, window_size, disparity_range, matching_function) disparity_maps.append((disparity_map, window_size, matching_function, disparity_range)) dmin, dmax = disparity_range visualize_disparity_map( disparity_map, gt_map, save_path=f"output/task1_{img_name}_{window_size}_{dmin}_{dmax}_{matching_function}.png") return disparity_maps def task2_compute_depth_map(disparity_map, baseline, focal_length): '''Compute depth map by z = fB / (x - x') Note that a disparity less or equal to zero should be ignored (set to zero) ''' disp = disparity_map.astype(np.float32) # OpenCV StereoBM uses fixed-point disparity (scaled by 16); try to auto-handle it. if np.issubdtype(disp.dtype, np.integer) or disp.max() > 512: # Heuristic: if values are large, it's likely scaled if disp.max() > 512: disp = disp / 16.0 depth_map = np.zeros_like(disp, dtype=np.float32) valid = disp > 0 depth_map[valid] = (float(focal_length) * float(baseline)) / disp[valid] return depth_map def task2_visualize_pointcloud( ref_img: np.ndarray, # shape (H, W, 3) disparity_map: np.ndarray, # shape (H, W) save_path: str = 'output/task2_tsukuba.ply' ): '''Visualize 3D pointcloud from disparity map following the steps: 1. Calculate depth map from disparity 2. Set pointcloud's XY as image's XY and and pointcloud's Z as depth 3. Set pointcloud's color as ref_img's color 4. Save pointcloud to ply files for visualizationh. We recommend to open ply file with MeshLab 5. Adjust the baseline and focal_length for better performance 6. You may need to cut some outliers for better performance ''' baseline = 10 focal_length = 10 depth_map = task2_compute_depth_map(disparity_map, baseline, focal_length) # Points H, W = depth_map.shape xs, ys = np.meshgrid(np.arange(W, dtype=np.float32), np.arange(H, dtype=np.float32)) # Keep only valid depths and drop far outliers valid = depth_map > 0 if np.any(valid): z = depth_map[valid] z_max = np.percentile(z, 99) # cut extreme far points valid = valid & (depth_map <= z_max) points = np.stack([xs[valid], ys[valid], depth_map[valid]], axis=1) # Colors # trimesh expects colors in RGB ref_rgb = ref_img[..., ::-1] colors = ref_rgb[valid].reshape(-1, 3).astype(np.uint8) # Save pointcloud to ply file pointcloud = trimesh.PointCloud(points, colors) os.makedirs(os.path.dirname(save_path), exist_ok=True) pointcloud.export(save_path, file_type='ply') def task3_compute_disparity_map_dp(ref_img, sec_img): ''' Conduct stereo matching with dynamic programming ''' ref = ref_img.astype(np.float32) sec = sec_img.astype(np.float32) H, W = ref.shape # Hyperparameters for DP occlusion_penalty = 20.0 max_disparity = 64 # only allow matches with disparity <= this value disparity_map_dp = np.zeros((H, W), dtype=np.float32) t0 = time.perf_counter() for r in tqdm(range(H), desc="DP stereo", leave=False): L = ref[r] R = sec[r] # DP tables (only lower triangle is used: j <= i) dp = np.full((W + 1, W + 1), np.inf, dtype=np.float32) move = np.zeros((W + 1, W + 1), dtype=np.uint8) # 0=match, 1=occL, 2=occR dp[0, 0] = 0.0 for i in range(1, W + 1): dp[i, 0] = dp[i - 1, 0] + occlusion_penalty move[i, 0] = 1 # Fill DP (j from 1..i) for i in range(1, W + 1): li = L[i - 1] for j in range(1, i + 1): # Match only if disparity is within range if (i - j) <= max_disparity: c_match = dp[i - 1, j - 1] + abs(li - R[j - 1]) else: c_match = np.inf c_occL = dp[i - 1, j] + occlusion_penalty c_occR = dp[i, j - 1] + occlusion_penalty if c_match <= c_occL and c_match <= c_occR: dp[i, j] = c_match move[i, j] = 0 elif c_occL <= c_occR: dp[i, j] = c_occL move[i, j] = 1 else: dp[i, j] = c_occR move[i, j] = 2 # Backtracking from (W, W) i, j = W, W while i > 0 or j > 0: m = move[i, j] if i > 0 and j > 0 and m == 0: disparity_map_dp[r, i - 1] = float(i - j) i -= 1 j -= 1 elif i > 0 and (j == 0 or m == 1): disparity_map_dp[r, i - 1] = 0.0 i -= 1 else: j -= 1 t1 = time.perf_counter() print(f"[Task3] DP runtime: {t1 - t0:.3f}s (occlusion={occlusion_penalty}, max_disp={max_disparity})") return disparity_map_dp def main(tasks): # Read images and ground truth disparity maps moebius_img1 = cv2.imread("data/moebius1.png") moebius_img1_gray = cv2.cvtColor(moebius_img1, cv2.COLOR_BGR2GRAY) moebius_img2 = cv2.imread("data/moebius2.png") moebius_img2_gray = cv2.cvtColor(moebius_img2, cv2.COLOR_BGR2GRAY) moebius_gt = cv2.imread("data/moebius_gt.png", cv2.IMREAD_GRAYSCALE) tsukuba_img1 = cv2.imread("data/tsukuba1.jpg") tsukuba_img1_gray = cv2.cvtColor(tsukuba_img1, cv2.COLOR_BGR2GRAY) tsukuba_img2 = cv2.imread("data/tsukuba2.jpg") tsukuba_img2_gray = cv2.cvtColor(tsukuba_img2, cv2.COLOR_BGR2GRAY) tsukuba_gt = cv2.imread("data/tsukuba_gt.jpg", cv2.IMREAD_GRAYSCALE) # Task 0: Visualize cv2 Results if '0' in tasks: # Compute disparity maps using cv2 stereo = cv2.StereoBM.create(numDisparities=64, blockSize=15) moebius_disparity_cv2 = stereo.compute(moebius_img1_gray, moebius_img2_gray) visualize_disparity_map(moebius_disparity_cv2, moebius_gt) tsukuba_disparity_cv2 = stereo.compute(tsukuba_img1_gray, tsukuba_img2_gray) visualize_disparity_map(tsukuba_disparity_cv2, tsukuba_gt) if '2' in tasks: print('Running task2 with cv2 results ...') task2_visualize_pointcloud(tsukuba_img1, tsukuba_disparity_cv2, save_path='output/task2_tsukuba_cv2.ply') ###################################################################### # Note. Running on moebius may take a long time with your own code # # In this homework, you are allowed only to deal with tsukuba images # ###################################################################### # Task 1: Simple Disparity Algorithm if '1' in tasks: print('Running task1 ...') disparity_maps = task1_simple_disparity(tsukuba_img1_gray, tsukuba_img2_gray, tsukuba_gt, img_name='tsukuba') ##################################################### # If you want to run on moebius images, # # parallelizing with multiprocessing is recommended # ##################################################### # task1_simple_disparity(moebius_img1_gray, moebius_img2_gray, moebius_gt, img_name='moebius') if '2' in tasks: print('Running task2 with disparity maps from task1 ...') for (disparity_map, window_size, matching_function, disparity_range) in disparity_maps: dmin, dmax = disparity_range task2_visualize_pointcloud( tsukuba_img1, disparity_map, save_path=f'output/task2_tsukuba_{window_size}_{dmin}_{dmax}_{matching_function}.ply') # Task 3: Non-local constraints if '3' in tasks: print('----------------- Task 3 -----------------') tsukuba_disparity_dp = task3_compute_disparity_map_dp(tsukuba_img1_gray, tsukuba_img2_gray) visualize_disparity_map(tsukuba_disparity_dp, tsukuba_gt, save_path='output/task3_tsukuba.png') if '2' in tasks: print('Running task2 with disparity maps from task3 ...') task2_visualize_pointcloud(tsukuba_img1, tsukuba_disparity_dp, save_path='output/task2_tsukuba_dp.ply') if __name__ == '__main__': # Set tasks to run parser = argparse.ArgumentParser(description='Homework 4') parser.add_argument('--tasks', type=str, default='0123') args = parser.parse_args() main(args.tasks) 修改一下这个代码,严格按照题目要求,并且一定要彩色!彩色!彩色!写全代码,谢谢
11-28
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值