21_Non_Midline_Y_Connection














































% ========== 步骤7: 对每条裂隙轮廓提取并计算 JRC ========== fprintf('📐 开始计算每条裂隙的 JRC 粗糙度...\n'); jrcResults = struct(); % 存储每条裂隙的不同采样方法下的 JRC for fissureIdx = 1:length(fissureResults) fprintf('🔍 处理第 %d 条裂隙...\n', fissureIdx); % 获取该裂隙内点 % 获取该裂隙内点 x_inlier = fissureResults(fissureIdx).inliers_x; y_inlier = fissureResults(fissureIdx).inliers_y; % === 步骤1: 对每个 x 位置的多个 y 取平均 === [unique_x, ~, idx] = unique(round(x_inlier)); mean_y = accumarray(idx, y_inlier, [], @mean); % 排序 [unique_x, sort_idx] = sort(unique_x); mean_y = mean_y(sort_idx); X_raw = unique_x; Y_raw = mean_y; % === 步骤2: 高密度插值生成平滑轮廓 === if length(X_raw) < 2 fprintf('⚠️ 第%d条裂隙有效点不足,跳过。\n', fissureIdx); continue; end % 生成等间距的查询点 xq = linspace(min(X_raw), max(X_raw), 1000); % 使用 spline 插值(或 pchip 防止过冲) try Y_interp = interp1(X_raw, Y_raw, xq, 'pchip', 'extrap'); catch ME fprintf('❌ 插值失败:%s\n', ME.message); continue; end % 去除 NaN valid = ~isnan(Y_interp); X_dense = xq(valid); Y_dense = Y_interp(valid); % 提取轮廓:使用 Canny 边缘检测从当前裂隙掩膜中获取清晰边界 mask_current = false(height, width); R_fit = fissureResults(fissureIdx).params(1); P_fit = fissureResults(fissureIdx).params(2); beta_fit = fissureResults(fissureIdx).params(3); C_fit = fissureResults(fissureIdx).params(4); x_all = 1:width; y_curve = R_fit * sin(2*pi/P_fit*(x_all - beta_fit)) + C_fit; half_width = 30; for x = 1:width yc = y_curve(x); if isnan(yc) || yc < 1 || yc > height, continue; end y_low = max(1, floor(yc - half_width)); y_high = min(height, ceil(yc + half_width)); mask_current(y_low:y_high, x) = true; end se = strel('disk', 3); mask_current = imclose(double(mask_current), se) > 0; % 使用 canny 边缘检测提取上下两个边界 edge_map = edge(uint8(mask_current), 'canny', [], 0.1); [y_edge, x_edge] = find(edge_map); if isempty(x_edge) fprintf('⚠️ 第%d条裂隙未提取到边缘!跳过。\n', fissureIdx); continue; end % 将边缘点聚类为上边缘和下边缘(根据纵坐标中位数划分) midline_y = median([fissureResults(fissureIdx).inliers_y]); upper_edge = (y_edge < midline_y); lower_edge = ~upper_edge; % 取其中一个边缘作为代表(比如下边缘更完整) x_contour = x_edge(lower_edge); y_contour = y_edge(lower_edge); if length(x_contour) < 10 fprintf('⚠️ 边缘点太少,跳过第%d条裂隙。\n', fissureIdx); continue; end % 按 x 排序 [~, idx_sort] = sort(x_contour); x_contour = x_contour(idx_sort); y_contour = y_contour(idx_sort); % 平滑轮廓(可选) y_contour = smoothdata(y_contour, 'gaussian', 5); % 准备三种采样方式 num_samples = 100; % 统一采样点数量便于比较 methods = {'uniform', 'adaptive', 'random'}; jrcValues = zeros(1, 3); for m = 1:3 method = methods{m}; x_sampled = []; y_sampled = []; switch method case 'uniform' % 等间隔采样 x idx_uniform = round(linspace(1, length(x_contour), num_samples)); idx_uniform = unique(idx_uniform); x_sampled = x_contour(idx_uniform); y_sampled = y_contour(idx_uniform); case 'adaptive' % 自适应采样:曲率大处多采样 dx = diff(x_contour); dy = diff(y_contour); ddx = diff([0, dx]); % 近似二阶导 ddy = diff([0, dy]); % 计算每个点的曲率近似 |d²y/dx²| / (1 + (dy/dx)^2)^(3/2) slopes = dy ./ (dx + eps); curvature = abs([0, diff(slopes)]) ./ (1 + [slopes(1:end-1).^2, 0]).^1.5; % 根据曲率加权概率分布采样 prob = curvature + 0.01; % 加小常数避免零权重 cumprob = cumsum(prob); total = cumprob(end); rand_vals = rand(1, num_samples) * total; idx_adaptive = interp1(cumprob, 1:length(cumprob), rand_vals, 'linear', 'nearest'); idx_adaptive = unique(round(idx_adaptive)); x_sampled = x_contour(idx_adaptive); y_sampled = y_contour(idx_adaptive); case 'random' % 随机采样 idx_rand = randperm(length(x_contour), min(num_samples, length(x_contour))); idx_rand = sort(idx_rand); % 保持顺序 x_sampled = x_contour(idx_rand); y_sampled = y_contour(idx_rand); end % 计算 Z 参数 dx_samp = diff(x_sampled); dy_samp = diff(y_sampled); N = length(dx_samp); if N == 0 Z = 0; else Z = sqrt(sum((dy_samp ./ (dx_samp + eps)).^2) / N); end % 计算 JRC JRC = 51.85 * (Z^0.6) - 10.37; JRC = max(JRC, 0); % 防止负值 jrcValues(m) = JRC; fprintf('📊 [%s 采样] Z=%.4f, JRC=%.2f\n', method, Z, JRC); end % 保存结果 jrcResults(fissureIdx).x_contour = x_contour; jrcResults(fissureIdx).y_contour = y_contour; jrcResults(fissureIdx).JRC_uniform = jrcValues(1); jrcResults(fissureIdx).JRC_adaptive = jrcValues(2); jrcResults(fissureIdx).JRC_random = jrcValues(3); jrcResults(fissureIdx).mean_JRC = mean(jrcValues); end % 输出总体统计 all_jrc = [jrcResults.JRC_uniform, jrcResults.JRC_adaptive, jrcResults.JRC_random]; fprintf('✅ 所有裂隙 JRC 计算完成!平均 JRC ≈ %.2f\n', mean(all_jrc)); 修改语法错误
09-23
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值