Loading Image From SD Card
Posted: Thu Oct 24, 2024 8:19 am
I have tested the SD Card Example(SDMMC) on my ESP32 Cam and it is working fine. My objective is to load the jpg image from the SD Card and count the white pixels in it. I have written a script to load the image but when i count the number of white pixels it print out different number each time on the same image. Can any one help me debug this issue ?
Here is the script i am using in C language.
Here is the script i am using in C language.
Code: Select all
#include <stdio.h>
#include <stdlib.h>
#include "esp_log.h"
#include "esp_err.h"
#include "sdmmc_cmd.h"
#include "esp_vfs_fat.h"
#include "driver/sdmmc_host.h"
#define TAG "football_detection"
#define WHITE_PIXEL_THRESHOLD 5600
#define MOUNT_POINT "/sdcard"
// Function to detect football in the zoomed-in ROI
bool detect_football_in_zoomed_roi(uint8_t* frame, int width, int height, int white_pixel_threshold) {
int white_pixel_count = 0;
// Calculate zoomed-in ROI (30% from each side)
int x_crop = width * 0.30;
int y_crop = height * 0.30;
int roi_width = width - 2 * x_crop;
int roi_height = height - 2 * y_crop;
// Debugging info: Print image size and calculated ROI
ESP_LOGI(TAG, "Image width: %d, height: %d", width, height);
ESP_LOGI(TAG, "Zoomed-in ROI: x=%d, y=%d, width=%d, height=%d", x_crop, y_crop, roi_width, roi_height);
// Traverse through the ROI and count white pixels
for (int y = y_crop; y < y_crop + roi_height; ++y) {
for (int x = x_crop; x < x_crop + roi_width; ++x) {
int i = (y * width + x) * 3; // Position in the RGB frame buffer (3 bytes per pixel)
uint8_t r = frame[i]; // Red component
uint8_t g = frame[i + 1]; // Green component
uint8_t b = frame[i + 2]; // Blue component
// Detect white pixels: Using a high RGB value as white (e.g., R > 200, G > 200, B > 200)
if (r > 200 && g > 200 && b > 200) {
white_pixel_count++;
}
}
}
// Debugging info: Print the total number of white pixels detected
ESP_LOGI(TAG, "Total white pixels detected: %d", white_pixel_count);
// Return true if the number of white pixels exceeds the threshold
return white_pixel_count > white_pixel_threshold;
}
// Function to read the image file and ensure it loads perfectly into memory
static esp_err_t load_image_file(const char *path, uint8_t **image_buffer, size_t *image_size) {
FILE *file = fopen(path, "rb");
if (!file) {
ESP_LOGE(TAG, "Failed to open image file: %s", path);
return ESP_FAIL;
}
// Get the file size
fseek(file, 0, SEEK_END);
*image_size = ftell(file);
fseek(file, 0, SEEK_SET);
ESP_LOGI(TAG, "Image file size: %zu bytes", *image_size);
// Allocate memory for the image buffer
*image_buffer = (uint8_t*)malloc(*image_size);
if (!(*image_buffer)) {
ESP_LOGE(TAG, "Failed to allocate memory for image buffer.");
fclose(file);
return ESP_ERR_NO_MEM;
}
// Read the image file into the buffer
size_t bytes_read = fread(*image_buffer, 1, *image_size, file);
fclose(file);
// Ensure the file was read fully
if (bytes_read != *image_size) {
ESP_LOGE(TAG, "Failed to read the complete image file. Bytes read: %zu", bytes_read);
free(*image_buffer);
return ESP_FAIL;
}
ESP_LOGI(TAG, "Image loaded successfully.");
return ESP_OK;
}
// Function to load image and detect football
static esp_err_t process_image(const char *image_path) {
uint8_t *image_buffer = NULL;
size_t image_size = 0;
// Load the image from SD card
esp_err_t err = load_image_file(image_path, &image_buffer, &image_size);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Error loading image.");
return err;
}
// Assuming 320x240 RGB image for simplicity (adjust based on your image)
int width = 320;
int height = 240;
// Detect football in the zoomed-in ROI
bool football_detected = detect_football_in_zoomed_roi(image_buffer, width, height, WHITE_PIXEL_THRESHOLD);
if (football_detected) {
ESP_LOGI(TAG, "football detected.");
} else {
ESP_LOGI(TAG, "No football detected.");
}
// Free the image buffer after use
free(image_buffer);
return ESP_OK;
}
void app_main(void) {
esp_err_t ret;
// SD card mount configuration (adapted from Code 1)
esp_vfs_fat_sdmmc_mount_config_t mount_config = {
#ifdef CONFIG_EXAMPLE_FORMAT_IF_MOUNT_FAILED
.format_if_mount_failed = true, // Conditional formatting based on menuconfig
#else
.format_if_mount_failed = false, // Do not format if mounting fails
#endif
.max_files = 5, // Allow up to 5 files open simultaneously
.allocation_unit_size = 16 * 1024 // Allocation unit size of 16 KB
};
// Configure SDMMC Host and Slot (adapted from Code 1)
sdmmc_host_t host = SDMMC_HOST_DEFAULT();
sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();
slot_config.width = 1;
#ifdef CONFIG_EXAMPLE_SDMMC_BUS_WIDTH_4
slot_config.width = 4; // Use 4-bit mode if configured
#else
slot_config.width = 1; // Default to 1-bit mode
#endif
slot_config.flags |= SDMMC_SLOT_FLAG_INTERNAL_PULLUP; // Enable internal pull-ups
// Mount SD card filesystem
sdmmc_card_t *card;
ret = esp_vfs_fat_sdmmc_mount(MOUNT_POINT, &host, &slot_config, &mount_config, &card);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to mount SD card filesystem.");
return;
}
ESP_LOGI(TAG, "SD card mounted.");
// Process the image (change the path if needed)
const char *image_path = MOUNT_POINT "/noDB1.jpg";
ret = process_image(image_path);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to process image.");
}
// Unmount SD card
esp_vfs_fat_sdcard_unmount(MOUNT_POINT, card);
ESP_LOGI(TAG, "SD card unmounted.");
}