要退后一步,我的最终目标是将大约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()
,但无法在每一行上都这样做,并且将结果放在一个数据帧中而不会耗尽内存。任何帮助都会很棒。谢谢!
答案 0 :(得分:1)
鉴于问题的含糊不清,这很难回答,但我将举一个可重复的示例,说明我在想什么,并给出解决方案。
说我有一个返回数据帧的函数:
MyFun <- function(x)randu[1:x,]
我有一个数据框df
,它将充当该函数的输入。
# a b
# 1 1 21
# 2 2 22
# 3 3 23
# 4 4 24
# 5 5 25
# 6 6 26
# 7 7 27
# 8 8 28
# 9 9 29
# 10 10 30
从您的问题来看,似乎只有一栏将用作输入。因此,我使用lapply
将函数应用于此数据帧的每一行,然后使用do.call
和rbind
将结果绑定在一起,如下所示:
do.call(rbind, lapply(df$a, MyFun))