I am trying to save the captured images for OV7670 camera module using Raspberry pi pico.I have written a code in CircuitPython to save the image in bmp format.But when i try to download the image from pico and view, i am getting a pixelated image.I am beginner to pico and CircuitPython.So please guide me where my code is wrong and what to be changed.
I have tried using this code
CODE:
import time
import storage
from displayio import (
Bitmap,
Group,
TileGrid,
FourWire,
release_displays,
ColorConverter,
Colorspace,
)
import displayio
from adafruit_st7789 import ST7789
from adafruit_bitmapsaver import save_pixels
import board
import busio
import digitalio
from adafruit_ov7670 import (
OV7670,
OV7670_SIZE_DIV1,
OV7670_SIZE_DIV16,
)
# Set up the display (You must customize this block for your display!)
release_displays()
spi = busio.SPI(clock=board.GP2, MOSI=board.GP3)
display_bus = FourWire(spi, command=board.GP0, chip_select=board.GP1, reset=None)
display = ST7789(display_bus, width=320, height=240, rotation=270)
# Ensure the camera is shut down, so that it releases the SDA/SCL lines,
# then create the configuration I2C bus
with digitalio.DigitalInOut(board.GP10) as reset:
reset.switch_to_output(False)
time.sleep(0.001)
bus = busio.I2C(board.GP9, board.GP8)
# Set up the camera (you must customize this for your board!)
cam = OV7670(
bus,
data_pins=[
board.GP12,
board.GP13,
board.GP14,
board.GP15,
board.GP16,
board.GP17,
board.GP18,
board.GP19,
], # [16] [org] etc
clock=board.GP11, # [15] [blk]
vsync=board.GP7, # [10] [brn]
href=board.GP21, # [27/o14] [red]
mclk=board.GP20, # [16/o15]
shutdown=None,
reset=board.GP10,
) # [14]
width = 320
height = 240
bitmap = displayio.Bitmap(cam.width, cam.height, 65535)
g = Group(scale=1, x=(width - bitmap.width) // 2, y=(height - bitmap.height) // 2)
tg = TileGrid(
bitmap, pixel_shader=ColorConverter(input_colorspace=Colorspace.RGB565_SWAPPED)
)
g.append(tg)
# BMP header
bmp_header = bytearray(54) #The size of the bmp header file (max size)
bmp_header[0:2] = b"BM" # first 2 bytes Signature of the BMP file
bmp_header[2:6] = (cam.width * cam.height * 2 + 54).to_bytes(4, "little") # next 4 bytes is File size
bmp_header[10:14] = (54).to_bytes(4, "little") # Offset indicates the offset from start of the file to begining of the data
bmp_header[14:18] = (40).to_bytes(4, "little") # Info header size
bmp_header[18:22] = cam.width.to_bytes(4, "little") # Image width
bmp_header[22:26] = cam.height.to_bytes(4, "little") # Image height
bmp_header[26:28] = (8).to_bytes(4, "little") # Planes
bmp_header[28:30] = (16).to_bytes(2, "little") # Bits per pixel
t0 = time.monotonic_ns()
#display.auto_refresh = False
count = 0
while True:
count = count + 1
cam.capture(bitmap)
bitmap.dirty()
#display.refresh(minimum_frames_per_second=0)
t1 = time.monotonic_ns()
print("fps", 1e9 / (t1 - t0))
t0 = t1
bim = bytearray(bitmap)
image_size = len(bim) * 2 # Multiply by 2 bytes per pixel
file_size = 54 + image_size
bmp_header[2:6] = (file_size).to_bytes(4, 'little')
# Save the image as a BMP file
bmp_data = bmp_header + bim
with open('efpsl.bmp', 'wb') as f:
f.write(bmp_data)
if count == 3:
break
Image: