Maze Solving Robot Using OpenCV
by engineerkid1 in Circuits > Robots
153 Views, 2 Favorites, 0 Comments
Maze Solving Robot Using OpenCV
In this project, I built a maze solving robot that uses an Android phone camera and OpenCV to navigate through a maze autonomously.
Unlike traditional maze-solving robots that depend on multiple IR sensors, this robot uses computer vision to detect the path and make decisions in real time. The robot follows black maze lines using OpenCV image processing and solves the maze using the Left-Hand Rule algorithm.
For getting the raw frames, I used an IP Camera App that transmits the frames to my computer wirelessly. The computer then analyzes those frames and sends the movement command to the ESP32 on the robot via TCP (You can also use Bluetooth here) and it sends the commands to the Arduino which move the robot.
The robot has total 7 moves - forward, stop, left, right, u-turn, adjust left and adjust right.
The actual maze solving is explained in below steps.
There are two phases in the operation-
- Learning phase - In this phase the robot navigates the entire maze until it finds the end spot.
- Solving phase - In this phase the robot deduces the shortest path to reach the end spot and then traverses that path.
This project combines:
- Computer Vision
- Robotics
- OpenCV
- Arduino
- Autonomous Navigation
This can be a great hobby project or a mini project for your college work.
Supplies
Electronics
- Arduino Uno x 1
- ESP32 x 1
- 28BYJ-48 Stepper Motor x 2
- ULN 2003 Driver x 2
- Buck converter x 1 (12->5V)
- Robot Chassis x 1
- Wheels (Good Grip) x 2
- Castor Wheel (Smooth) x 1
- L-ion Battery Pack 12V x 1 (Contest people you see this)
- Jumper Wires
Software
- Arduino IDE
- Python with OpenCV and other dependencies installed
- IP camera App
Mechanical
- Black electrical tape
- White floor/chart paper
Building the Maze
I built the maze by sticking a black electrical tape directly onto my white floor. You can use a white cardboard sheet or banner if you want.
I followed the attached maze for my project. Feel free to use any other maze of your choice, just remember below points.
Important:
- Avoid enclosed loops if using Left-Hand Maze Solving Rule
- Keep line width consistent
- Use high contrast between path and background
- Avoid glossy surfaces if possible so the robot gets a better grip
The robot works best when:
- The maze has proper junctions
- Turns are sharp and clean
- Lighting is consistent
Building the Robot
The ESP32 communicates with the Arduino UNO using UART serial communication.
ESP32 Pin -> Arduino UNO Pin
GPIO1 (TX0) -> Pin 0 (RX)
GPIO3 (RX0) -> Pin 1 (TX)
GND -> GND
5V VCC -> 5V
Arduino UNO Pin -> ULN 2003 -> Left Motor
Pin 7 -> IN1
Pin 6 -> IN2
Pin 5 -> IN3
Pin 4 -> IN4
Arduino UNO Pin -> ULN 2003 -> Right Motor
Pin 8 -> IN1
Pin 9 -> IN2
Pin 10 -> IN3
Pin 11 -> IN4
Overall Architecture
IP Camera → OpenCV on PC → ESP32 (WiFi TCP) → Arduino UNO → ULN2003 Drivers → Stepper Motors
How the Maze Solving Algorithm Works
The robot solves the maze using computer vision instead of traditional IR sensors.
Rather than detecting lines using dedicated hardware sensors, the robot uses an IP camera feed and OpenCV to “see” the maze and make decisions in real time.
The overall idea is surprisingly simple:
- Look at different regions of the camera image
- Count black pixels in those regions
- Decide where the path exists
- Move accordingly
The Camera View
The maze consists of:
- Black path
- White floor
The camera continuously captures frames of the maze from above.
Each frame is converted into a black-and-white image so the robot can easily separate the maze path from the background.
Region-Based Detection
Instead of analyzing the entire image, the frame is divided into multiple smaller zones.
Each zone has a specific purpose.
Bottom Zone – Path Following
The bottom region is used to keep the robot centered on the path.
The algorithm compares the black pixel distribution in this region:
- If more black pixels appear on the left side, the robot adjusts left
- If more black pixels appear on the right side, the robot adjusts right
- If the path is centered, the robot moves forward
This works similarly to a basic OpenCV line follower robot project I made earlier.
Left and Right Zones – Turn Detection
The side regions detect available turns.
If the left zone contains enough black pixels:
- A left turn exists
If the right zone contains enough black pixels:
- A right turn exists
These regions allow the robot to identify intersections inside the maze.
Top Zone – Dead Ends and T-Intersections
The top region helps the robot understand what lies ahead.
This region is used to detect:
- Dead ends
- Straight paths
- T-intersections
If no black pixels are detected ahead:
- The robot concludes that it has reached a dead end
- It performs a U-turn
Top-Right Zone – Finish Detection
A small region near the top-right corner is used as the finish detector.
When this region along with the other regions detects the final black marker:
- The robot concludes that the maze is solved
The robot continuously follows this logic:
- Check for left turn
- Check for straight path
- If straight path exists → move forward
- Continuously make small corrections to stay centered
- Check for right turn
- If no path exists → perform U-turn
The camera feed is processed repeatedly in real time, allowing the robot to constantly update its movement decisions. And the turns and movements recorded are from the robot's perspective.
Recovery Logic for Overshooting
One major problem with the robot was inconsistent turning caused by the inexpensive stepper motors.
Sometimes the robot:
- Turned too little (undershoot)
- Turned too much (overshoot)
I designed a simple mechansim to test the stepper motor and driver using Autodesk Fusion 360 and quickly printed it using my trusted Bambu Lab A1 mini. Uploaded a simple script to tirn the motor continuously and let it run for several hours. I observed that the initial position of the servo and the final position were off by a very little marning. But this test was under no load. Now imagine what would be happening to my robot when it is under entire load of the chassis, phone, ardino, esp32 and not to forget the big Li-ION Battery (I did it again).
To solve this, I added a recovery system.
After every turn:
- The robot assumes it has undershot the turn
- It starts making small correction movements in the turning direction
- If no valid path is found after several attempts, it assumes the opposite problem occurred
- It then starts correcting in the opposite direction
This solution is time consuming but it allowed the robot to recover from positioning errors without using expensive encoders or sensors.
Shortest Path Logic
After solving the maze once, the robot stores the sequence of turns it took.
The algorithm below then simplifies unnecessary movements to generate a shorter and more efficient route.
simplification_rules = {
('left', 'u-turn', 'right'): 'u-turn',
('left', 'u-turn', 'forward'): 'right',
('right', 'u-turn', 'left'): 'u-turn',
('forward', 'u-turn', 'left'): 'right',
('forward', 'u-turn', 'forward'): 'u-turn',
('left', 'u-turn', 'left'): 'forward',
}
This optimized path is later used during the speed run phase.
In the video, my robot traversed {right, right, left, left, right, u-turn, left, left, right, u-turn, left, left, right}
So the shortest path is calculated as follows -
- {right, right, left, left, right, u-turn, left, left, right, u-turn, left, left, right} -> RUL=U
- {right, right, left, left, u-turn, left, u-turn, left, left, right} -> LUL=F
- {right, right, left, fwd, u-turn, left, right} -> FUL=R
- {right, right, left, right, right}
So our shortest path became - {right, right, left, right, right}
Source Code
Arduino Code
ESP32 Code
Python Code
Final Result & Future Improvements
The final robot can:
- Detect maze paths visually
- Make autonomous decisions
- Solve mazes using computer vision
- Replay optimized shortest paths
This project demonstrates how low-cost robotics combined with OpenCV can create powerful autonomous systems without expensive sensors.
Future Improvements
- Replace the 28BYJ-48 motors with faster and more accurate motors
- Move OpenCV processing to a Raspberry Pi or Jetson Nano for a fully standalone robot
- Increase camera frame rate to improve turn detection accuracy
- Better path planning algorithms
That's it for now. Thank you for reading this instructable. Hope this helped you. If it did then let me know by commenting. If you have any doubts or suggesstions, feel free to reach out.