【问题标题】:Convert grayscale image to point cloud (similar to dither)将灰度图像转换为点云(类似于抖动)
【发布时间】:2014-05-27 13:14:58
【问题描述】:

我目前正在尝试实现一种方法来生成TSP art,为此我需要一个点列表 (x,y),其局部密度与给定图像的灰度像素值成正比.

我的第一个想法是:嗯,这很像 Inverse Transform Sampling 用于统计(你想绘制一个匹配给定概率密度函数的样本,但你只能创建一个均匀分布的样本)。

我实现了这个,它运行得相当好,通过执行这段代码可以看出:

%% Load image, adjust it for our needs
im=imread('http://goo.gl/DDwV3t');  %load random headshot from google
im=imadjust(im,stretchlim(im,[.01,.65]),[]);
im=im2double(rgb2gray(im));
im=im(10:end-5,50:end-5);
figure;imshow(im);title('original');

im=1-im; %we want black dots on white background
im=flipud(im); %and we want it the right way up

%% process per row
imrow = cumsum(im,2);
imrow=imrow*size(imrow,1)./repmat(max(imrow,[],2),1,size(imrow,2));
y=1:size(imrow,2);
ximrow_i = zeros(size(imrow));
for i = 1:size(imrow,1)
    mask =logical([diff(imrow(i,:))>=0.01,0]); %needed for interp
    ximrow_i(i,:) = interp1(imrow(i,mask),y(mask),y);
end
y=1:size(ximrow_i,1);
y=repmat(y',1,size(ximrow_i,2));

y1=y(1:5:end,1:5:end);   %downscale a bit
ximcol_i1=ximrow_i(1:5:end,1:5:end); %downscale a bit
figure('Color','w');plot(ximcol_i1(:),y1(:),'k.');title('Inverse Transform Sampling on rows');
axis equal;axis off;

%% process per column
imcol=cumsum(im,1);
imcol=imcol*size(imcol,2)./repmat(max(imcol,[],1),size(imcol,1),1);
y=1:size(imcol,1);

yimcol_i=zeros(size(imcol));
for i = 1:size(imcol,2)
    mask =logical([diff(imcol(:,i))>=0.01;0]);
    yimcol_i(:,i) = interp1(imcol(mask,i),y(mask),y);
end
y=1:size(imcol,2);
y=repmat(y,size(imcol,1),1);

y1=y(1:5:end,1:5:end);
yimcol_i1=yimcol_i(1:5:end,1:5:end);
figure('Color','w');plot(y1(:),yimcol_i1(:),'k.');title('Inverse Transform Sampling on cols');
axis equal;axis off;

它的缺点是我只能按行或按列使用,但不能同时使用。逆变换采样方法通常不适用于多变量 PDF,我很确定在这种情况下我无法让它工作。

有没有一种简单的方法可以实现我还没有看到的目标?

我知道一种称为 Voronoi Stippler 的算法已被用于创建所需的结果,我将对此进行调查,但目前我喜欢逆变换采样的简单性,并想知道我是否可以将该方法扩展到符合我的需要。

【问题讨论】:

  • im2 = rand(size(im))<im; ?
  • 是的,差不多就是这样。在自己研究和实施之后,我发现了你的评论:)

标签: matlab image-processing statistics probability-density


【解决方案1】:

事实证明这是相当简单的,可以通过Rejection Sampling来完成。

对于工具分布为 U(0,1) 的特殊情况,它的工作原理如下(如果我理解正确的话):

im=imread('http://goo.gl/DDwV3t');  %load random headshot from google
im=imadjust(im,stretchlim(im,[.01,.65]),[]);
im=im2double(rgb2gray(im));
im=im(10:end-5,50:end-5);
im=1-flipud(im);

d = im > .9*rand(size(im));
d=d&(rand(size(d))>.95);  %randomly sieve out some more points
[i,j]=ind2sub(size(d),find(d));
figure('Color','w');plot(j,i,'k.');title('Rejection Sampling');
axis equal;axis off;

采样在一行中完成:

d = im > .9*rand(size(im));

由于我最终得到的点太多,我对结果进行了随机抽样,从而将点数减少了大约 20 倍。

这几乎是我最初想要的结果。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多