【发布时间】:2018-08-23 17:30:58
【问题描述】:
退一步说,我的最终目标是将大约 130,000 张图像读入 R 中,像素大小为 HxW,然后制作一个数据帧/数据表,其中包含新行上每个图像的每个像素的 rgb。所以输出会是这样的:
> head(train_data, 10)
image_no r g b pixel_no
1: 00003e153.jpg 0.11764706 0.1921569 0.3098039 1
2: 00003e153.jpg 0.11372549 0.1882353 0.3058824 2
3: 00003e153.jpg 0.10980392 0.1843137 0.3019608 3
4: 00003e153.jpg 0.11764706 0.1921569 0.3098039 4
5: 00003e153.jpg 0.12941176 0.2039216 0.3215686 5
6: 00003e153.jpg 0.13333333 0.2078431 0.3254902 6
7: 00003e153.jpg 0.12549020 0.2000000 0.3176471 7
8: 00003e153.jpg 0.11764706 0.1921569 0.3098039 8
9: 00003e153.jpg 0.09803922 0.1725490 0.2901961 9
10: 00003e153.jpg 0.11372549 0.1882353 0.3058824 10
我目前有一段代码来执行此操作,其中我应用了一个函数来获取指定图像的每个像素的 rgb,并在数据帧中返回结果:
#function to get rgb from image file paths
get_rgb_table <- function(link){
img <- readJPEG(toString(link))
# Creating the data frame
rgb_image <- data.frame(r = as.vector(img[1:H, 1:W, 1]),
g = as.vector(img[1:H, 1:W, 2]),
b = as.vector(img[1:H, 1:W, 3]))
#add pixel id
rgb_image$pixel_no <- row.names(rgb_image)
#add image id
train_rgb <- cbind(sub('.*/', '',link),rgb_image)
colnames(train_rgb)[1] <- "image_no"
return(train_rgb)
}
我在另一个包含所有图像链接的数据帧上调用此函数:
train_files <- list.files(path="~/images/", pattern=".jpg",all.files=T, full.names=T, no.. = T)
train <- data.frame(matrix(unlist(train_files), nrow=length(train_files), byrow=T))
火车数据框如下所示:
> head(train, 10)
link
1 C:/Documents/image/00003e153.jpg
2 C:/Documents/image/000155de5.jpg
3 C:/Documents/image/00021ddc3.jpg
4 C:/Documents/image/0002756f7.jpg
5 C:/Documents/image/0002d0f32.jpg
6 C:/Documents/image/000303d4d.jpg
7 C:/Documents/image/00031f145.jpg
8 C:/Documents/image/00053c6ba.jpg
9 C:/Documents/image/00057a50d.jpg
10 C:/Documents/image/0005d01c8.jpg
我终于通过以下循环得到了我想要的结果:
for(i in 1:length(train[,1])){
train_data <- rbind(train_data,get_rgb_table(train[i,1]))
}
但是,最后一段代码效率很低。优化如何应用函数和/或 rbind 会有所帮助。我认为函数get_rgb_table() 本身很快,但问题在于循环和rbind。我曾尝试使用apply(),但无法在每一行上执行此操作并将结果放入一个数据帧中而不会耗尽内存。对此的任何帮助都会很棒。谢谢!
【问题讨论】:
-
你没有说你的函数做了什么,也没有说你的输入和输出数据是什么样的。人们很难提供帮助。您是要仅优化
rbind部分还是“将函数应用于数据帧的每一行”部分? -
data.table::rbindlist()应该快得多,但这似乎是一个有问题的过程,循环遍历 data.frame,可能有更好的方法。 -
我认为@avid_user 建议解释函数的作用,因为通常有比将函数应用于每一行更有效的解决方案。
-
在 R 中增长东西通常很糟糕,尤其是对于数据帧,因为它非常慢且内存效率低下。如果您事先知道结果应该有多少行,您可以启动一个具有该大小的数据框并用循环生成的结果填充它。
-
感谢摩西的建议,我也试试看!
标签: r image-processing