将灰度图像转换为点云(类似于抖动)

时间:2014-05-27 13:14:58

标签: matlab image-processing statistics probability-density

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

我的第一个想法是:对于统计数据来说,它的工作方式与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的算法已用于创建所需的结果,我将对此进行调查,但目前我喜欢Inverse Transform Sampling的简单性,并且想知道我是否可以将该方法扩展到符合我的需要。

1 个答案:

答案 0 :(得分: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倍。

这几乎是我原本想要的结果。