Skip to content

Commit

Permalink
Merge pull request #28 from arduino-libraries/marqdevx/vision-shield/…
Browse files Browse the repository at this point in the history
…bitmap-SD

Portenta Vision Shield, bitmap to SD Card update sketch
  • Loading branch information
marqdevx authored Aug 23, 2022
2 parents cddb73e + 8dcd04d commit 0e9b96b
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 81 deletions.
Original file line number Diff line number Diff line change
@@ -1,126 +1,144 @@
#include "SDMMCBlockDevice.h" // Multi Media Card APIs
#include "FATFileSystem.h" // Mbed API for portable and embedded systems
#include "FATFileSystem.h" // API to run operations on a FAT file system
SDMMCBlockDevice blockDevice;
mbed::FATFileSystem fileSystem("fs");

#include "camera.h" // Arduino Mbed Core Camera APIs
#include "himax.h" // Exclusive Camera library for the Portenta Vision Shield
#include "himax.h" // API to read from the Himax camera found on the Portenta Vision Shield
HM01B0 himax;
Camera cam(himax);

FrameBuffer fb; // Buffer to save the capture
FrameBuffer frameBuffer; // Buffer to save the camera stream

// Settings for our setup
#define RES_H (unsigned int)240
#define RES_W (unsigned int)320
#define IMAGE_HEIGHT (unsigned int)240
#define IMAGE_WIDTH (unsigned int)320
#define IMAGE_MODE CAMERA_GRAYSCALE
#define IMAGE_BPP (unsigned int)8
#define BITS_PER_PIXEL (unsigned int)8
#define PALETTE_COLORS_AMOUNT (unsigned int)(pow(2, BITS_PER_PIXEL))
#define PALETTE_SIZE (unsigned int)(PALETTE_COLORS_AMOUNT * 4) // 4 bytes = 32bit per color (3 bytes RGB and 1 byte 0x00)
#define IMAGE_PATH "/fs/image.bmp"

// Headers info
#define HEADER_FILE_HEADER (unsigned int)14
#define HEADER_DIB_SIZE (unsigned int)40
#define HEADER_FULL_SIZE (HEADER_FILE_HEADER + HEADER_DIB_SIZE)
#define PALETTE_SIZE (2 ^ IMAGE_BPP) * 4 // 4 bytes per color
#define BITMAP_FILE_HEADER_SIZE (unsigned int)14 // For storing general information about the bitmap image file
#define DIB_HEADER_SIZE (unsigned int)40 // For storing information about the image and define the pixel format
#define HEADER_SIZE (BITMAP_FILE_HEADER_SIZE + DIB_HEADER_SIZE)

void setup()
{
Serial.begin(115200);
while (!Serial)
;

// Mount SD Card
mountSD();
void setup(){
Serial.begin(115200);
while (!Serial && millis() < 5000);

Serial.println("Mounting SD Card...");
mountSDCard();
Serial.println("SD Card mounted.");

// Init the cam QVGA, 30FPS, Grayscale
if (!cam.begin(CAMERA_R320x240, IMAGE_MODE, 30))
{
if (!cam.begin(CAMERA_R320x240, IMAGE_MODE, 30)){
Serial.println("Unable to find the camera");
}

// Save the headers and the image data into the .bmp file
parseData();
countDownBlink();
Serial.println("Fetching camera image...");
unsigned char *imageData = captureImage();
digitalWrite(LEDB, HIGH);

Serial.println("Saving image to SD card...");
saveImage(imageData, IMAGE_PATH);

fileSystem.unmount();
Serial.println("Done. You can now remove the SD card.");
}

void loop()
{
while (1)
;
void loop(){
}

// Mount File system block
void mountSD()
{
Serial.println("Mounting SD Card...");

void mountSDCard(){
int error = fileSystem.mount(&blockDevice);
if (error)
{
Serial.println("No SD Card found");
while (1)
;
if (error){
Serial.println("Trying to reformat...");
int formattingError = fileSystem.reformat(&blockDevice);
if (formattingError) {
Serial.println("No SD Card found");
while (1);
}
}
}

void parseData()
{
unsigned char *imgData = NULL;
int fileSize = HEADER_FILE_HEADER + RES_W * RES_H;

FILE *file = fopen("/fs/image.bmp", "w+");

// Get a Frame
if (cam.grabFrame(fb, 3000) == 0)
{
// Save the raw image data (8bpp grayscale)
imgData = fb.getBuffer();
}
else
{
// Get the raw image data (8bpp grayscale)
unsigned char * captureImage(){
if (cam.grabFrame(frameBuffer, 3000) == 0){
return frameBuffer.getBuffer();
} else {
Serial.println("could not grab the frame");
while (1)
;
while (1);
}
// Bitmap structure (Head + DIB Head + ColorMap + binary image)
unsigned char bitmapFileHeader[HEADER_FILE_HEADER];
unsigned char bitmapDIBHeader[HEADER_DIB_SIZE];
unsigned char colorMap[PALETTE_SIZE]; // Needed for <=8bpp grayscale bitmaps
}

// Set the file headers to 0
memset(bitmapFileHeader, (unsigned char)(0), HEADER_FILE_HEADER);
memset(bitmapDIBHeader, (unsigned char)(0), HEADER_DIB_SIZE);
memset(colorMap, (unsigned char)(0), PALETTE_SIZE);
// Set the headers data
void setFileHeaders(unsigned char *bitmapFileHeader, unsigned char *bitmapDIBHeader, int fileSize){
// Set the headers to 0
memset(bitmapFileHeader, (unsigned char)(0), BITMAP_FILE_HEADER_SIZE);
memset(bitmapDIBHeader, (unsigned char)(0), DIB_HEADER_SIZE);

// Write the headers info
// File header
bitmapFileHeader[0] = 'B';
bitmapFileHeader[1] = 'M';
bitmapFileHeader[2] = (unsigned char)(fileSize);
bitmapFileHeader[3] = (unsigned char)(fileSize >> 8);
bitmapFileHeader[4] = (unsigned char)(fileSize >> 16);
bitmapFileHeader[5] = (unsigned char)(fileSize >> 24);
bitmapFileHeader[10] = (unsigned char)HEADER_FULL_SIZE + PALETTE_SIZE;
bitmapFileHeader[10] = (unsigned char)HEADER_SIZE + PALETTE_SIZE;

// Info header
bitmapDIBHeader[0] = (unsigned char)(HEADER_DIB_SIZE);
bitmapDIBHeader[4] = (unsigned char)(RES_W);
bitmapDIBHeader[5] = (unsigned char)(RES_W >> 8);
bitmapDIBHeader[8] = (unsigned char)(RES_H);
bitmapDIBHeader[8] = (unsigned char)(RES_H >> 8);
bitmapDIBHeader[14] = (unsigned char)(IMAGE_BPP);

// Color palette for grayscale Bitmaps (8bpp)
for (int i = 0; i < (2 ^ IMAGE_BPP); i++)
{
bitmapDIBHeader[0] = (unsigned char)(DIB_HEADER_SIZE);
bitmapDIBHeader[4] = (unsigned char)(IMAGE_WIDTH);
bitmapDIBHeader[5] = (unsigned char)(IMAGE_WIDTH >> 8);
bitmapDIBHeader[8] = (unsigned char)(IMAGE_HEIGHT);
bitmapDIBHeader[9] = (unsigned char)(IMAGE_HEIGHT >> 8);
bitmapDIBHeader[14] = (unsigned char)(BITS_PER_PIXEL);
}

void setColorMap(unsigned char *colorMap){
//Init the palette with zeroes
memset(colorMap, (unsigned char)(0), PALETTE_SIZE);

// Gray scale color palette, 4 bytes per color (R, G, B, 0x00)
for (int i = 0; i < PALETTE_COLORS_AMOUNT; i++) {
colorMap[i * 4] = i;
colorMap[i * 4 + 1] = i;
colorMap[i * 4 + 2] = i;
}
}

// Save the headers and the image data into the .bmp file
void saveImage(unsigned char *imageData, const char* imagePath){
int fileSize = BITMAP_FILE_HEADER_SIZE + DIB_HEADER_SIZE + IMAGE_WIDTH * IMAGE_HEIGHT;
FILE *file = fopen(imagePath, "w");

// Write theh bitmap file
fwrite(bitmapFileHeader, 1, HEADER_FILE_HEADER, file);
fwrite(bitmapDIBHeader, 1, HEADER_DIB_SIZE, file);
fwrite(colorMap, 1, PALETTE_SIZE, file); // Color map
fwrite(imgData, 1, RES_H * RES_W, file);
// Bitmap structure (Head + DIB Head + ColorMap + binary image)
unsigned char bitmapFileHeader[BITMAP_FILE_HEADER_SIZE];
unsigned char bitmapDIBHeader[DIB_HEADER_SIZE];
unsigned char colorMap[PALETTE_SIZE]; // Needed for <= 8bpp grayscale bitmaps

setFileHeaders(bitmapFileHeader, bitmapDIBHeader, fileSize);
setColorMap(colorMap);

// Write the bitmap file
fwrite(bitmapFileHeader, 1, BITMAP_FILE_HEADER_SIZE, file);
fwrite(bitmapDIBHeader, 1, DIB_HEADER_SIZE, file);
fwrite(colorMap, 1, PALETTE_SIZE, file);
fwrite(imageData, 1, IMAGE_HEIGHT * IMAGE_WIDTH, file);

// Close the stream (bitmap file)
// Close the file stream
fclose(file);
}

void countDownBlink(){
for (int i = 0; i < 6; i++){
digitalWrite(LEDG, i % 2);
delay(500);
}
digitalWrite(LEDG, HIGH);
digitalWrite(LEDB, LOW);
}
6 changes: 3 additions & 3 deletions library.properties
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
name=Arduino_Pro_Tutorials
version=1.0.5
version=1.0.6
author=Martino Facchin, Riccardo Ricco, Dario Pennisi, Sebastian Romero, Lenard George, Ignacio Herrera, Jose García, Pablo Marquínez
maintainer=Arduino <info@arduino.cc>
sentence=This library contains the complete Arduino sketches from the Pro Tutorials.
paragraph=Instructions on how to use these sketches can be found on the Arduino Pro website under Documentation->Tutorials.
category=Other
url=https://www.arduino.cc/pro/tutorials/portenta-h7
architectures=mbed,mbed_portenta
url=https://docs.arduino.cc/#pro-family
architectures=mbed,mbed_portenta,mbed_nicla,mbed_edge
precompiled=false
depends=lvgl

0 comments on commit 0e9b96b

Please sign in to comment.