Free tutorials & notes in Hindi & English · Clean code examples 🧰 Free PDF & Image Tools →
🟣 ML + AI  ·  Lesson 34

Computer Vision with OpenCV

In this lesson: Computer vision with OpenCV — read, resize, grayscale, edge detection and face detection — beginner Python code. In Hindi & English.

What is computer vision?

Computer vision teaches computers to understand images and video: reading number plates, scanning documents, counting products on a shelf, detecting faces for attendance or checking cracks in a road. OpenCV is the most widely used open-source library for it, and in Python an image is simply a NumPy array of pixel values.

Terminal
pip install opencv-python matplotlib

Step 1: an image is a NumPy array

We use a real photo that ships with scikit-learn, so you can run every example without downloading anything.

Python – image_array.py
import cv2
from sklearn.datasets import load_sample_image

rgb = load_sample_image("flower.jpg")          # NumPy array in RGB order
img = cv2.cvtColor(rgb, cv2.COLOR_RGB2BGR)     # OpenCV works in BGR order
cv2.imwrite("flower.jpg", img)                 # save it like any photo

img = cv2.imread("flower.jpg")                 # how you load your own photo
print("type :", type(img).__name__, img.dtype)
print("shape:", img.shape, "→ height, width, channels")
print("pixel at row 100, col 200 (B, G, R):", img[100, 200])
print("brightest value:", img.max(), "| darkest:", img.min())
type : ndarray uint8 shape: (427, 640, 3) → height, width, channels pixel at row 100, col 200 (B, G, R): [22 22 6] brightest value: 255 | darkest: 0
⚠️ OpenCV uses BGR, not RGB

cv2.imread returns channels in Blue-Green-Red order. Matplotlib expects RGB, so convert with cv2.cvtColor(img, cv2.COLOR_BGR2RGB) before showing, or your red flowers will look blue.

Step 2: resize, crop, grayscale, blur

Python – basics.py
import cv2
import matplotlib.pyplot as plt
from sklearn.datasets import load_sample_image

img = cv2.cvtColor(load_sample_image("flower.jpg"), cv2.COLOR_RGB2BGR)

small = cv2.resize(img, (320, 214))                        # (width, height)
crop = img[100:330, 180:480]                               # rows, columns – plain NumPy slicing
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(img, (21, 21), 0)                  # kernel size must be odd

print("small:", small.shape, "| crop:", crop.shape, "| gray:", gray.shape)

show = [("original", img), ("crop", crop), ("grayscale", gray), ("blur", blur)]
fig, axes = plt.subplots(1, 4, figsize=(12, 2.8), dpi=100)
for ax, (title, im) in zip(axes, show):
    ax.imshow(im if im.ndim == 2 else cv2.cvtColor(im, cv2.COLOR_BGR2RGB), cmap="gray")
    ax.set_title(title); ax.axis("off")
fig.tight_layout(); fig.savefig("basics.png")
small: (214, 320, 3) | crop: (230, 300, 3) | gray: (427, 640)
Original, cropped, grayscale and blurred versions of a flower photo

A grayscale image has only one channel, so its shape loses the last “3”. Many algorithms work on grayscale because colour is not needed and it is three times less data.

Step 3: edges and thresholding

Python – edges.py
import cv2
import matplotlib.pyplot as plt
from sklearn.datasets import load_sample_image

gray = cv2.cvtColor(load_sample_image("china.jpg"), cv2.COLOR_RGB2GRAY)

edges = cv2.Canny(gray, 100, 200)                                   # strong intensity changes
_, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)   # Otsu picks the cut-off
print("edge pixels:", int((edges > 0).sum()), "of", edges.size)

fig, axes = plt.subplots(1, 3, figsize=(12, 3.2), dpi=100)
for ax, (t, im) in zip(axes, [("grayscale", gray), ("Canny edges", edges), ("Otsu threshold", binary)]):
    ax.imshow(im, cmap="gray"); ax.set_title(t); ax.axis("off")
fig.tight_layout(); fig.savefig("edges.png")
edge pixels: 43072 of 273280
Grayscale photo, Canny edge map and Otsu black-and-white threshold
TechniqueWhat it givesUsed for
CannyThin lines where brightness changes sharplyDocument borders, lane lines, shapes
ThresholdPure black/white imageScanning text, separating objects from background
Blur firstRemoves noise before edges/thresholdCleaner results on phone photos

Step 4: count objects with contours

A classic factory task: count coins (or tablets, or biscuits) on a tray. We draw a test tray so the answer is known, then let OpenCV find each object’s outline (contour).

Python – count_coins.py
import cv2
import numpy as np

rng = np.random.default_rng(3)
tray = np.full((300, 500, 3), (60, 90, 40), np.uint8)               # green tray (BGR)
coins = [(70, 70, 32), (180, 90, 26), (300, 70, 36), (420, 100, 30),
         (100, 210, 28), (240, 210, 40), (390, 220, 25)]
for x, y, r in coins:
    cv2.circle(tray, (x, y), r, (40, 180, 220), -1)                  # golden coins
tray = cv2.add(tray, rng.integers(0, 25, tray.shape, dtype=np.uint8))  # camera noise

gray = cv2.cvtColor(tray, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (5, 5), 0)
_, mask = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = [c for c in contours if cv2.contourArea(c) > 200]         # ignore tiny specks

print("coins found:", len(contours), "| actual:", len(coins))
for c in sorted(contours, key=cv2.contourArea, reverse=True)[:3]:
    (x, y), r = cv2.minEnclosingCircle(c)
    print(f"  coin at ({x:.0f}, {y:.0f}) radius ≈ {r:.0f}px")

out = tray.copy()
cv2.drawContours(out, contours, -1, (0, 0, 255), 3)
cv2.putText(out, f"{len(contours)} coins", (10, 290), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (255, 255, 255), 2)
cv2.imwrite("counted.png", out)
coins found: 7 | actual: 7 coin at (240, 210) radius ≈ 40px coin at (300, 70) radius ≈ 36px coin at (70, 70) radius ≈ 32px
Seven coins on a tray outlined in red with the text 7 coins

Step 5: face detection on your own photo

OpenCV ships with pre-trained Haar cascade face detectors. Save a group photo as class.jpg next to this script and run it. It finds faces only – it does not know who they are.

Python – detect_faces.py (use your own photo)
import cv2

detector = cv2.CascadeClassifier(cv2.data.haarcascades + "haarcascade_frontalface_default.xml")
img = cv2.imread("class.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = detector.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(40, 40))
print("faces found:", len(faces))
for (x, y, w, h) in faces:
    cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv2.imwrite("class_faces.jpg", img)
🔐 Privacy

Photos of people are personal data. Use your own photos or ask permission, never upload other people’s faces to online tools, and follow your school’s or company’s rules for attendance systems.

Haar cascades are fast but old. Modern projects use deep-learning detectors (OpenCV’s DNN module, MediaPipe, YOLO), which handle side faces and poor light much better.

Webcam video in a loop

Python – webcam_edges.py (run on your computer)
import cv2

cap = cv2.VideoCapture(0)                  # 0 = default webcam
while True:
    ok, frame = cap.read()
    if not ok:
        break
    edges = cv2.Canny(cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY), 80, 160)
    cv2.imshow("edges – press q to quit", edges)
    if cv2.waitKey(1) & 0xFF == ord("q"):
        break
cap.release()
cv2.destroyAllWindows()

A video is just many images per second; every technique above works frame by frame.

Project ideas

ProjectTechniques
Document scanner (crop and straighten a page)Canny, contours, perspective transform
Tablet/biscuit counter for a production lineThreshold, contours, area filter
Colour-based object tracker (a ball)HSV colour mask, contours, video loop
Attendance helper (with consent)Face detection + a recognition model

Photo credits

Sample photos bundled with scikit-learn: flower.jpg by vultilion and china.jpg by danielbuechele on Flickr, licensed CC BY 2.0. The processed versions above were made with the code on this page.

Practice tasks

  1. Load your own photo, print its shape, and save a grayscale copy.
  2. Change the Canny thresholds to (50, 150) and (150, 250) and compare.
  3. Add two touching coins in Step 4 and see what happens to the count – then try cv2.erode to separate them.
  4. Make a mask of only red pixels using cv2.inRange on an HSV image.

Summary

  • Images are NumPy arrays: (height, width, channels); OpenCV uses BGR.
  • Crop with slicing, resize with cv2.resize, convert with cv2.cvtColor.
  • Blur → threshold/Canny → contours is the classic pipeline for finding and counting objects.
  • Haar cascades detect faces quickly; deep-learning detectors are more accurate.
  • Treat photos of people as private data.

Frequently Asked Questions

What is the difference between opencv-python and opencv-contrib-python?
opencv-python has the main modules. opencv-contrib-python adds extra, sometimes experimental modules (for example some feature detectors and face recognisers). Install only one of them in a venv.
Do I need deep learning for computer vision?
Not always. Counting objects on a plain background, scanning documents and colour tracking work well with classic OpenCV. Recognising many object types in messy real-world photos needs deep learning models such as YOLO.
← Back to Python Tutorial
🔗

Share this topic with a friend

यह topic किसी दोस्त को भेजें

Found it useful? Send it to a classmate learning the same thing.

अच्छा लगा? जो दोस्त यही सीख रहा है, उसे भेज दीजिए।

💻 Live Code Editor

This page's programs are ready here — run them, edit them, and learn. No installation needed.
Powered by OneCompiler. The code loads into the editor automatically — press Run to see the output. If the editor does not open, open it in a new tab.
Next topicGenerative AI and LLM Basics Your progress: 34 / 66 (52%) · Lesson 35 / 66 Continue →

How was this lesson?

Your feedback helps us make the content better.

Write a review or suggestion (optional)

After approval, your name and city may appear publicly with your review. Please do not write your email or phone number.

▶ CodingEasily on YouTube

Learn with video lessons in easy Hindi

Featured video: RDBMS Part 3 – Class XI Commerce IT

▶ Subscribe – it’s free