Smooth 2D surface of surface plot
조회 수: 8 (최근 30일)
이전 댓글 표시
Hello,
The attached object has been constructed from an hemi-ellipsoid and an hemisphere. The curvature of the object however is not smooth everywhere.
Is there a way to make it smooth and to store the new coordinates Xsmooth , Ysmooth and Zsmooth of the object to reconstruct it with surf(Xsmooth, Ysmooth, Zsmooth)?
Thank you in advance for your help!
댓글 수: 3
Image Analyst
2021년 5월 1일
Can you post a screenshot (PNG file) so we can see it here instead of having to dowload the .fig file, switch to MATLAB, then open it there? Make it easy for us to help you.
DGM
2021년 5월 1일
I set shading flat and camlight on to help illustrate that the surface is quite smooth except for the step caused by misalignment.
채택된 답변
DGM
2021년 5월 1일
편집: DGM
2021년 5월 2일
If the goal is to improve the smoothness of the volume of rotation, then we should go back to that. There are a few things we could do, but I have a feeling that if you're building the approximation from primitives, then the exactness of the shape isn't terribly important. I'll just throw some stuff at it. Let's start with the lumpy eggplant we left off with:
On one hand, we can try smoothing the source object image and do some oversampling to try to get a better curve to begin with:
%% do the same thing, but oversampling
clc; clf; clear variables
IM = imread('pear.jpg');
E = imbinarize(IM);
object=bwareafilt(E,1);
% try to smooth the image
resamplefactor = 4;
object = imfilter(double(object),fspecial('disk',20));
object = imresize(object,resamplefactor)>0.5;
% i guess the object is already centered at y=140
A = regionprops(object,'centroid');
ycenter = A.Centroid(2);
% select the upper curve
[~,upper] = max(object);
xextent = [find(upper>1,1,'first') find(upper>1,1,'last')];
upper = ycenter-upper(upper>1); % trim off invalid radii
% close the curve
upper([1,end]) = 0;
Ncirc = 200; % number of faces around circumference
Nlong = 300; % number of faces along length
% rescale and resample to specified resolution
xextent = xextent/resamplefactor;
x0 = linspace(xextent(1),xextent(2),numel(upper));
xf = linspace(xextent(1),xextent(2),Nlong);
upper = interp1(x0,upper,xf,'linear')/resamplefactor;
% one last bit of smoothing
upper = smooth(upper,20);
% run the surf plot
[Y Z X] = cylinder(upper,Ncirc);
surf(X*diff(xextent)+xextent(1),Y,Z)
axis equal
shading flat
colormap(ccmap)
camlight
That's better, but it still is a bit lumpy in spots. If that's not smooth enough, maybe we can discard the curve and replace it with a spline approximation:
%% do the same thing, but do a curve fit
clc; clf; clear variables
IM = imread('pear.jpg');
E = imbinarize(IM);
object=bwareafilt(E,1);
% try to smooth the image
resamplefactor = 2;
object = imfilter(double(object),fspecial('disk',20));
object = imresize(object,resamplefactor)>0.5;
% i guess the object is already centered at y=140
A = regionprops(object,'centroid');
ycenter = A.Centroid(2);
% select the upper curve
[~,upper] = max(object);
xextent = [find(upper>1,1,'first') find(upper>1,1,'last')];
upper = ycenter-upper(upper>1); % trim off invalid radii
% close the curve
upper([1,end]) = 0;
Ncirc = 200; % number of faces around circumference
Nlong = 200; % number of faces along length
xextent = xextent/resamplefactor;
x0 = linspace(xextent(1),xextent(2),numel(upper));
xf = linspace(xextent(1),xextent(2),Nlong);
upper = interp1(x0,upper,xf,'linear')/resamplefactor;
% smooth the thing with a spline fit
fm = fit(xf',upper','smoothingspline','smoothingparam',0.01);
upper = fm(xf);
upper([1,end]) = 0;
% run the surf plot
[Y Z X] = cylinder(upper,Ncirc);
surf(X*diff(xextent)+xextent(1),Y,Z)
axis equal
shading flat
colormap(ccmap)
camlight
That's a lot better, but idk if you have fit(). There may be some other smoothing spline tools in the base toolbox or on the FEX.
추가 답변 (1개)
참고 항목
카테고리
Help Center 및 File Exchange에서 Surface and Mesh Plots에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!