# Basic image processing using OpenCV
import cv2
import requests
import numpy as np
import matplotlib.pyplot as plt
from io import BytesIO
# Fetch the image from the URL using requests
url = 'https://images.unsplash.com/photo-1444464666168-49d633b86797?w=800&auto=format&fit=crop&q=60&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MXx8YmlyZHxlbnwwfHwwfHx8Mg%3D%3D'
response = requests.get(url)
image = np.asarray(bytearray(response.content), dtype="uint8")
image = cv2.imdecode(image, cv2.IMREAD_COLOR)
# Convert the image to grayscale
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# Apply a Gaussian blur to the image
blurred_image = cv2.GaussianBlur(gray_image, (5, 5), 0)
# Detect edges using the Canny edge detection algorithm
edges = cv2.Canny(blurred_image, 100, 200)
# Display the original and processed images
plt.figure(figsize=(10, 7))
plt.subplot(2, 2, 1)
plt.title('Original Image')
plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
plt.axis('off')
plt.subplot(2, 2, 2)
plt.title('Grayscale Image')
plt.imshow(gray_image, cmap='gray')
plt.axis('off')
plt.subplot(2, 2, 3)
plt.title('Blurred Image')
plt.imshow(blurred_image, cmap='gray')
plt.axis('off')
plt.subplot(2, 2, 4)
plt.title('Edge Detection')
plt.imshow(edges, cmap='gray')
plt.axis('off')
plt.tight_layout()
plt.show()OpenCV is a computer vision library written in C++, and cv2 is its
Python interface. It reads and writes images, filters and transforms
them, and finds edges, shapes and features. Every image is a
NumPy array. People use it to process photos, detect
faces and objects, and analyse video. This page is an online
OpenCV compiler: the code runs in your browser, so you can try it
without installing anything.
Run the example first, then paste any snippet below into a new cell to try it.
requests.get() downloads a photo of a kingfisher, and
cv2.imdecode() decodes the JPEG bytes into a (534, 800, 3) array of
uint8 values: 534 rows, 800 columns and three colour channels. OpenCV
stores the channels in blue, green, red (BGR) order. cv2.cvtColor()
with cv2.COLOR_BGR2GRAY turns the photo into a single-channel grey
image. cv2.GaussianBlur() smooths it with a 5 by 5 kernel, and the 0
tells OpenCV to work out the blur strength from the kernel size.
cv2.Canny() then marks edges with two thresholds. Gradients above 200
become edges, and weaker ones down to 100 are kept only where they
connect to a strong edge. Without the blur, it would mark about twice as
many pixels. The result contains only 0 and 255. matplotlib draws the
four images in a 2 by 2 grid. It expects RGB, so the colour photo goes
through cv2.COLOR_BGR2RGB first.
Drawing functions change the array in place. Points are (x, y), colours
are (blue, green, red), and a thickness of -1 fills the shape.
cv2.imwrite() saves the result as shapes.png for the next snippets:
import cv2
import numpy as np
import matplotlib.pyplot as plt
canvas = np.full((300, 400, 3), 255, dtype=np.uint8) # 300 rows, 400 columns, white
cv2.rectangle(canvas, (30, 40), (150, 160), (255, 0, 0), -1) # blue square
cv2.circle(canvas, (270, 100), 60, (0, 0, 255), -1) # red circle
triangle = np.array([[60, 270], [140, 190], [220, 270]], np.int32)
cv2.fillPoly(canvas, [triangle], (0, 160, 0)) # green triangle
cv2.putText(canvas, "OpenCV", (240, 250), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 0), 2)
cv2.imwrite("shapes.png", canvas)
plt.imshow(cv2.cvtColor(canvas, cv2.COLOR_BGR2RGB))
plt.axis("off")
plt.show()
The next two snippets read shapes.png, so run this one first.
cv2.threshold() turns the image into a black and white mask,
cv2.findContours() traces each white region, and cv2.approxPolyDP()
reduces an outline to its corners:
import cv2
img = cv2.imread("shapes.png")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
_, mask = cv2.threshold(gray, 200, 255, cv2.THRESH_BINARY_INV) # shapes white, background black
contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
print(len(contours), "outlines found")
for contour in contours:
area = cv2.contourArea(contour)
if area < 1000: # skip the letters
continue
corners = cv2.approxPolyDP(contour, 0.02 * cv2.arcLength(contour, True), True)
x, y, w, h = cv2.boundingRect(contour)
print(f"{len(corners)} corners, area {area:.0f}, box at x={x}, y={y}, {w}x{h}")
The six letters of "OpenCV" are outlines too, so nine are found. To use
your own photo, click Mount folder in the sidebar's Data tab (Chrome
or Edge on a computer), choose the folder it is in, and read it by name
with cv2.imread(). Add files does not take images.
cv2.resize() takes the new size as (width, height), but array shapes
and slices are (rows, columns). cv2.getRotationMatrix2D() builds a
rotation, counterclockwise for a positive angle, and cv2.warpAffine()
applies it:
import cv2
import matplotlib.pyplot as plt
img = cv2.imread("shapes.png")
print(img.shape) # (rows, columns, channels)
small = cv2.resize(img, (200, 150)) # (width, height)
cropped = img[40:161, 30:151] # rows first, then columns
flipped = cv2.flip(img, 1) # 1 mirrors left to right
h, w = img.shape[:2]
matrix = cv2.getRotationMatrix2D((w / 2, h / 2), 30, 1.0) # centre, angle, scale
rotated = cv2.warpAffine(img, matrix, (w, h), borderValue=(255, 255, 255))
print(small.shape, cropped.shape, flipped.shape, rotated.shape)
plt.imshow(cv2.cvtColor(rotated, cv2.COLOR_BGR2RGB))
plt.axis("off")
plt.show()
The rotated image keeps its size, so corners outside the frame are cut off.
cv2.imshow() and cv2.waitKey() do not work here: this OpenCV
build has no GUI support. Either call stops Python with a fatal error
that try/except cannot catch, and no more code runs until you
reload the page. Show images with plt.imshow() instead.cv2.imread() does not raise an error for a missing file. It prints
a warning and returns None, so check the result.uint8 images, cv2.add() stops at 255, while NumPy's + wraps
around: 250 + 10 gives 4.