This project converts an image into contour points and uses a Raspberry Pi Pico as a USB HID (Human Interface Device) to automatically draw the image in any paint application like MS Paint.
Screen.Recording.2025-10-16.120808.online-video-cutter.com.mp4
The project consists of two main components:
- Image Processing (
extract_contours.py): Converts an image into contour points using OpenCV - Drawing Automation (
code.py): Runs on Raspberry Pi Pico to simulate mouse movements and draw the contours
- Python 3.x
- OpenCV (
opencv-python)
- Raspberry Pi Pico or Pico W
- CircuitPython firmware
- Adafruit HID library
- USB cable to connect Pico to computer
Install OpenCV for image processing:
pip install opencv-python-
Install CircuitPython on your Pico:
- Download CircuitPython from circuitpython.org
- Hold the BOOTSEL button while plugging in the Pico to enter bootloader mode
- Drag and drop the CircuitPython
.uf2file onto theRPI-RP2drive - The Pico will reboot and appear as a
CIRCUITPYdrive
-
Install Adafruit HID Library:
- Download the Adafruit HID library from the CircuitPython Bundle
- Make sure you download a version mathing the CircuitPython SDK version.
- Copy the
adafruit_hidfolder to thelibfolder on yourCIRCUITPYdrive - The required library files are already included in the
libfolder of this repository
-
Copy Files to Pico:
- Copy
code.py,data.py, and thelibfolder to the root of yourCIRCUITPYdrive - If using a French keyboard layout, the
keycode_win_fr.mpyandkeyboard_layout_win_fr.mpyfiles are included - For other keyboard layouts, modify the import in
code.py
- Copy
-
Place your image file (PNG or JPG) in the project directory as
image.png -
Run the contour extraction script:
python extract_contours.py-
This will:
- Resize the image to 300x300 pixels
- Convert it to grayscale
- Apply binary thresholding
- Extract contours
- Save the contour points to
data.py - Display a preview of detected contours
-
Adjust threshold if needed:
- Open
extract_contours.pyand modify thethreshold_valueparameter (0-255) - Lower values detect more details, higher values detect only prominent features
- Default is 127
- Open
-
Safety Notice: The
code.pyfile has a safetyexit()line commented at line 15. Review the code before removing this safety feature. -
Open the
code.pyfile and remove or comment out the safety exit:#exit() # For safety, remove this line to run the script -
Save
code.pyto your Pico. The script will automatically run when the Pico boots. -
What the script does:
- Opens the Run dialog (Win+R) on Windows
- Types "paint.net" to open Paint.NET (you can modify this for MS Paint or other apps)
- Maximizes the window
- Moves the mouse to the starting position
- Draws all contours by:
- Moving the mouse to each point in the contour
- Pressing and holding the left mouse button
- Following the contour points
- Releasing the mouse button when the contour is complete
-
Customization:
- Modify the
scalevariable incode.py(line 61) to adjust drawing size - Change the keyboard commands to open different paint applications
- Adjust
time.sleep()values to change drawing speed
- Modify the
- Load and Resize: Image is loaded and resized to 300x300 pixels
- Grayscale Conversion: Color image is converted to grayscale
- Binary Thresholding: Pixels above threshold become white, below become black
- Contour Detection: OpenCV finds the outlines of white regions
- Data Export: Contour points are saved as Python lists in
data.py
- Initialization: Sets up USB HID keyboard and mouse
- Application Launch: Opens paint application using keyboard shortcuts
- Window Setup: Maximizes the window and positions mouse
- Drawing Loop: For each contour:
- Moves mouse to first point
- Presses left mouse button
- Moves through all points in the contour
- Releases mouse button
- Moves to next contour
The mouse movement is smoothed by breaking large movements into smaller steps to ensure accuracy.
Problem: No contours detected
- Solution: Adjust the
threshold_valueinextract_contours.py. Try values between 50-200.
Problem: Too many small contours
- Solution: Increase the threshold value or pre-process your image to have clearer edges
Problem: Pico not recognized as CIRCUITPY drive
- Solution: Reinstall CircuitPython firmware. Ensure you're using the correct version for your Pico model.
Problem: Import errors for adafruit_hid
- Solution: Ensure the
adafruit_hidfolder is in thelibdirectory on your Pico
Problem: Wrong keyboard layout
- Solution: Modify line 4 in
code.pyto import the correct keycode module for your keyboard layout
Problem: Drawing is too small/large
- Solution: Adjust the
scalevariable incode.py(line 61)
Problem: Drawing is too fast/slow
- Solution: Adjust the
time.sleep()values incode.pyto control movement speed
Problem: Paint application doesn't open
- Solution: Modify the keyboard commands in
code.pyto match your system:- For MS Paint (Windows): Replace "PAINT.NET" with "MSPAINT"
- For other applications: Adjust the key sequence accordingly
- Start with simple images (silhouettes, logos) before trying complex ones
- Ensure the paint application is the active window before drawing starts
- The 5-second delay (line 39) gives you time to prepare the canvas
- Test with the safety
exit()enabled first to verify keyboard commands work
The project currently uses French keyboard layout (keycode_win_fr). To use a different layout:
- Download the appropriate keyboard layout
- Place it in the
libfolder - Update line 4 in
code.py:from keycode_win_us import Keycode # For US keyboard
This project is open source. Feel free to modify and use it for your own projects.
Contributions are welcome! Feel free to submit issues or pull requests to improve the project.
- Uses CircuitPython for Raspberry Pi Pico
- Uses Adafruit HID Library for USB HID functionality
- Uses OpenCV for image processing