用R创建“艺术”马赛克图片(*不是*统计马赛克图)

时间:2012-09-03 18:34:46

标签: r graphics color-picker

我想稍微玩一下图像,并想知道R中是否有方法可以生成马赛克图片,如these

我想对于背景图片,人们可以使用readJPEGjpeg}和rasterImage来自graphics包。

但是我对于如何计算和聚类颜色值以及排列前景图片感到迷茫。

修改

我发现这个post“朝着正确的方向”。但我想如果你创造一个“真实”的马赛克,其中实际的图片纯粹由小图片组成(而不是像背景和前景图片的组合,并找到this example中正确的透明度),你有问题,你需要数百甚至数千张照片。

1 个答案:

答案 0 :(得分:13)

认为这是一个浪费几个小时的好挑战。这是一个概念证明函数:

library(jpeg)
library(png)
library(plyr)

reduceCol <-  function(x,dim=c(1,1))
{
  arr <- array(dim=c(nrow(x),ncol(x),4))
  cols <- col2rgb(c(x),alpha=TRUE)
  arr[,,1] <- matrix(cols[1,],nrow(x),ncol(x),byrow=TRUE)
  arr[,,2] <- matrix(cols[2,],nrow(x),ncol(x),byrow=TRUE)
  arr[,,3] <- matrix(cols[3,],nrow(x),ncol(x),byrow=TRUE)
  arr[,,4] <- matrix(cols[4,],nrow(x),ncol(x),byrow=TRUE)



  Res <- array(dim=c(dim,4))
  if (dim[1]>1) seqRows <- as.numeric(cut(1:nrow(x),dim[1])) else seqRows <- rep(1,nrow(x))
  if (dim[2]>1) seqCols <- as.numeric(cut(1:ncol(x),dim[2])) else seqCols <- rep(1,ncol(x))


  for (i in 1:dim[1])
  {
    for (j in 1:dim[2])
    { 
      for (z in 1:4)
      {
        Res[i,j,z] <- mean(arr[seqRows==i,seqCols==j,z])
      }
    }
  }
  return(Res)
}

rgbarr2colmat <- function(mat) 
{
  Res <- array(dim=dim(mat)[1:2])
  for (i in 1:dim(mat)[1])
  {
    for (j in 1:dim(mat)[2])
    {
      Res[i,j] <- rgb(mat[i,j,1],mat[i,j,2],mat[i,j,3],mat[i,j,4],maxColorValue=255)
    }
  }
  return(Res)
}

artymosaic <- function(BG,pics,res=c(10,10))
{
  BGreduced <- reduceCol(BG,res)
  Picmeancol <- lapply(pics,reduceCol)

  blockPic <- array(dim=res)
  for (i in 1:res[1])
  {
    for (j in 1:res[2])
    {
      blockPic[i,j] <- which.min(sapply(Picmeancol,function(x)sum(abs(BGreduced[i,j,]-x))))
    }
  }
  blockPic <- t(blockPic)
  blockPic <- blockPic[,ncol(blockPic):1]

  # Open empty plot:
  par(mar=c(0,0,0,0))
  plot(1,xlim=c(0,1),ylim=c(0,1),type="n",bty="n",axes=FALSE)

  # plot moasics:
  seqRows <- seq(0,1,length=res[1]+1)
  seqCols <- seq(0,1,length=res[2]+1)
  for (i in 1:res[1])
  {
    for (j in 1:res[2])
    {
      rasterImage(pics[[blockPic[i,j]]],seqRows[i],seqCols[j],seqRows[i+1],seqCols[j+1],interpolate=FALSE)
    }
  }
}

artymosaic使用栅格格式的背景作为第一个参数,栅格格式的图片列表作为第二个参数,分辨率(数字(2))作为第三个参数。

R徽标由计算机图片组成的示例。我下载了一些谷歌的图片,并将其上传到http://sachaem47.fortyseven.versio.nl/files/pics/mosaic.zip。如果这些是在马赛克文件夹中提取的,并且R徽标(http://cran.r-project.org/Rlogo.jpg)已下载到工作目录中,我们可以按照以下方式制作“艺术马赛克”。

bg <- readJPEG("Rlogo.jpg")
BG <- as.raster(bg)

jpgs <- lapply(list.files("mosaic/",pattern="\\.jpg",full.names=TRUE),readJPEG)
pics <- lapply(jpgs,as.raster)

png("test.png")
artymosaic(BG,pics,c(50,50))
dev.off()

enter image description here

看起来很棒吗?这里的主要缺点是我在适当的地方重复使用相同的图像,并且我只使用了很少的图像。这可以改变,但需要更多的图像,这将导致功能运行更长时间。再次,概念证明。