我正在尝试将未编码的图像用于植被绘图的遥感项目。我的设置是Raspberry Pi 3上的PiCamera v2 NoIR,附带的Roscolux#2007 StoraroBlue凝胶过滤器贴在传感器上,SenseHat用于环境测井。
我可以正常拍摄普通的PNG照片,但我无法弄清楚如何正确读取二进制数据,因为我的所有尝试都会导致条纹混乱。
以下是捕获图像的Python脚本部分:
def picamera_logging_thread():
logger.info('Started camera logging thread')
while time() < start_time + timeout:
with PiCamera() as camera:
# set values
camera.resolution = (3280, 2464)
# let automatic exposure settle
sleep(2)
image_name = 'image_' + str(int(time()))
# capture in PNG format at native resolution
camera.capture(os.path.join(image_dir, image_name + '.png'))
logger.info('Saved image ' + image_name + '.png')
# let automatic exposure settle
sleep(2)
image_name = 'image_' + str(int(time()))
# capture in unencoded RGB format
camera.capture(os.path.join(image_dir, image_name + '.bip'), 'rgb')
logger.info('Saved image ' + image_name + '.bip')
# delay the specified interval
sleep(picamera_logging_interval - 4)
logger.info('Stopped camera logging thread')
start_time = time()
# start logging threads
Thread(target = sensehat_logging_thread).start()
Thread(target = picamera_logging_thread).start()
使用picamera Python库捕获未编码RGB图像的在线文档说明了这一点:
生成的RGB数据是交错的。也就是说,给定像素的红色,绿色和蓝色值按此顺序组合在一起。数据的第一个字节是(0,0)处像素的红色值,第二个字节是同一像素的绿色值,第三个字节是该像素的蓝色值。第四个字节是(1,0)处像素的红色值,依此类推。
现在,我收集到这意味着生成的二进制数据将采用标准BIP(Band Interleaved by Pixel)格式,但我不确定他们的措辞是否会将像素分组为行或列,因为他们说第二个像素位于(1,0),这使我认为数据中的第二个像素位于第2行第1列而不是预期的第2列第1行。
我在R中编写了一个脚本,它将数据读取为1字节整数(0 - 255)的矩阵,并将它们添加到三个RasterLayer对象的RasterStack中,每个波段对应一个(RGB)。我甚至尝试添加.hdr
文件并在QGIS中打开它,但它始终是条纹噪音。
这是R脚本:
# This script parses BIP pixel data from a binary file, assuming order band first then rowwise
# imports
#install.packages("raster")
library(raster)
# define filename of binary data
binary_filename <- "image_1490191326.bip"
# define pixel dimensions of the data, width then height
pixel_dimensions <- c(width = 3280, height = 2464)
# open file connection in Binary Read mode
data_file <- file(binary_filename, "rb")
# get data (and upshift)
binary_data <-
readBin(
data_file,
what = "int",
size = 1,
n = pixel_dimensions["height"] * pixel_dimensions["width"] * 3 # hopefully the number of bytes in the file
) + 128 # upshift data from (-128, 127) to (0, 255) by adding 128
# close connection to file
close(data_file)
# create red raster layer of every 3rd byte, starting at the first one
red <-
raster(
matrix(binary_data[seq(from = 1,
to = length(binary_data),
by = 3)], nrow = pixel_dimensions["width"], ncol = pixel_dimensions["height"]),
ymn = pixel_dimensions["height"] / 2 * -1,
ymx = pixel_dimensions["height"] / 2,
xmn = pixel_dimensions["width"] / 2 * -1,
xmx = pixel_dimensions["width"] / 2
)
names(red) <- "red"
# create green raster layer of every 3rd byte, starting at the second one
green <-
raster(
matrix(binary_data[seq(from = 2,
to = length(binary_data),
by = 3)], nrow = pixel_dimensions["width"], ncol = pixel_dimensions["height"]),
ymn = pixel_dimensions["height"] / 2 * -1,
ymx = pixel_dimensions["height"] / 2,
xmn = pixel_dimensions["width"] / 2 * -1,
xmx = pixel_dimensions["width"] / 2
)
names(green) <- "green"
# create blue raster layer of every 3rd byte, starting at the third one
blue <-
raster(
matrix(binary_data[seq(from = 3,
to = length(binary_data),
by = 3)], nrow = pixel_dimensions["width"], ncol = pixel_dimensions["height"]),
ymn = pixel_dimensions["height"] / 2 * -1,
ymx = pixel_dimensions["height"] / 2,
xmn = pixel_dimensions["width"] / 2 * -1,
xmx = pixel_dimensions["width"] / 2
)
names(blue) <- "blue"
# create raster stack of the three layers
rgb_stack <- stack(red, green, blue)
# plot hopefully correct raster
plot(rgb_stack)
plotRGB(rgb_stack)
# remove unused large data variables from memory
rm(red, green, blue, binary_data)
我在这里做错了什么?我怎么读这个并提取可用的像素数据?
答案 0 :(得分:0)
啊哈!我想我已经解决了。图像实际上是在右边和底边填充了一些未使用的像素(在下图中您可以看到黑色),因此在原始图像的情况下,3280x2464
的公开尺寸不正确。正确的是3296x2464
,如果将这些数字相乘,然后乘以3(对于R,G和B像素),您将获得与您的文件相匹配的文件大小。
您可以使用 ImageMagick 将RGB
文件转换为JPEG
,该文件安装在大多数Linux发行版上,可用于macOS / OSX和Windows(以及Raspberry Pi) :
magick -depth 8 -size 3296x2464 image.rgb result.jpg
注意1 :如果您的文件名实际上并未以.rgb
结尾,则可以在其前面添加RGB:
,以便为ImageMagick提供有关其内容的提示,例如
magick -depth ... -size ... RGB:image.xyz ...
注意2 :如果您使用旧版ImageMagick,请将magick
替换为convert
。
注3 :如果您想使用ImageMagick裁掉黑色填充像素,请使用:
convert -depth 8 -size 3296x2464 image.rgb -trim result.jpg