Je tente de prendre des images non codées pour un projet de télédétection pour la cartographie de la végétation. Mon installation est un PiCamera v2 NoIR sur un Raspberry Pi 3, avec le filtre gel StoraroBlue Roscolux # 2007 inclus collé sur le capteur et un SenseHat pour l'enregistrement environnemental. Je peux prendre des photos PNG normales très bien, mais je n'arrive pas à comprendre comment lire les données binaires correctement, car toutes mes tentatives aboutissent à un désordre de couleurs.Comment lire des données binaires entrelacées à partir d'une caméra Raspberry Pi v2
Voici la section du script Python qui capture les images:
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()
La documentation en ligne pour la capture non codés images RVB à l'aide de la bibliothèque Python picamera dit ceci:
Les données résultantes RVB est entrelacé. C'est-à-dire que les valeurs rouge, verte et bleue pour un pixel donné sont regroupées, dans cet ordre. Le premier octet des données est la valeur rouge pour le pixel à (0, 0), le second octet est la valeur verte pour le même pixel, et le troisième octet est la valeur bleue pour ce pixel. Le quatrième octet est la valeur rouge pour le pixel à (1, 0), et ainsi de suite.
Maintenant, je crois que cela veut dire les données binaires résultantes seront à la norme PIF (Band Interleaved par pixel) format, mais je ne suis pas sûr que leur libellé infère les pixels sont regroupés en lignes ou colonnes, parce qu'ils disent le deuxième pixel est à (1, 0), ce qui me fait penser que le deuxième pixel dans les données est à la rangée 2, Colonne 1 à la place de la Colonne 2 attendue, Ligne 1.
J'ai écrit un script dans R qui lit les données sous la forme d'une matrice d'entiers de 1 octet (0 - 255) et les ajoute à un RasterStack de trois objets RasterLayer, un pour chaque bande (RGB). J'ai même essayé d'ajouter un fichier .hdr
et de l'ouvrir dans QGIS, mais c'est toujours du bruit rayé.
Voici le script 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)
ce que je fais mal ici? Comment pourrais-je lire ceci et extraire des données de pixels utilisables?
Pouvez-vous partager une image s'il vous plaît? –
chose sûre, édité pour ajouter des images –
Désolé, je veux dire l'image brute de BIP. –