DEPARTMENT OF COMPUTER & SOFTWARE ENGINEERING
COLLEGE OF E&ME, NUST, RAWALPINDI
EC 312 – Digital Image Processing
Lab # 02: Connected Component Analysis and Intensity
Resolution
Name Aleeza Rizwan
Registration Number 456143
Degree/ Syndicate CE 45 A
Instructor’s Name LE Umair Khalil
Lab Assessment
Post Lab Total
In-Lab Data
Data Analysis Writing Style
Presentation
1
Objectives:
To introduce some transformation, especially with respect to image processing.
To perform connected component labeling in images.
To get an understanding of intensity level resolution.
Lab Description:
Intensity level resolution defines the resolution at bit level i.e. how many bits are used to
represent a pixel value. The more bits we have per pixel, the more levels there are. For example,
a grayscale image has 256 different levels because for each pixel value we use 8 bits to store the
value. If the bits per pixel are decreased to 4, then the maximum levels that we can have is 16.
Similarly, if only 1 bit is used for it then we can have only two levels (or a binary image).
Task # 01:
A Distance map can be created by measuring the Euclidian distance of every pixel (position
in x and y) from the center and then assigning that value to the pixel for which the
Euclidian distance has been calculated.
Code:
#task01
import numpy as np
import cv2
import math
height = int(input('Enter the height of the image: '))
width = int(input('Enter the weight of the image: '))
distance_map = [Link]((height, width))
centre_x = height//2
centre_y = width//2
#loop to calculate distance from centre
for x in range(height):
for y in range(width):
distance_map[x, y] = [Link](((x-centre_x)**2) + ((y-
centre_y)**2))
max_dist = [Link](distance_map)
distance_map = distance_map/max_dist
[Link]("Distance Map", distance_map)
[Link]()
2
Output:
Figure 1.1: Console output of task 01
Figure 2.2: Image output of task 01
Explanation:
For this task, I wrote a program to generate a Euclidean distance map from the center of an image. The
user inputs the image dimensions, and the program calculates the Euclidean distance of each pixel from
the center. These distances are normalized to the range [0, 1] for display. The resulting image visualizes a
radial gradient where brightness corresponds to distance from the center.
Task # 02:
Read a grayscale image and convert the image to 16 levels, then to 4 levels and finally to 1.
Display all four images.
Code:
#task02
import cv2
3
import numpy as np
img = [Link]('[Link]', cv2.IMREAD_GRAYSCALE)
img = [Link](img, (1366, 768))
height, width = [Link]
output_16 = [Link]((height, width), dtype=np.uint8)
output_4 = [Link]((height, width), dtype=np.uint8)
output_1 = [Link]((height, width), dtype=np.uint8)
#loop for 16 levels
for xi in range(height):
for yi in range(width):
level = img[xi, yi] // 16
output_16[xi, yi] = level * 17
#loop for 4 levels
for xii in range(height):
for yii in range(width):
level = img[xii, yii] // 64
output_4[xii, yii] = level * 85
#loop for 1 levels
for xiii in range(height):
for yiii in range(width):
level = img[xiii, yiii] // 128
output_1[xiii, yiii] = level * 255
[Link]("Original Image", img)
[Link]("16-Level Gradient", output_16)
[Link]("4-Level Gradient", output_4)
[Link]("1-Level Gradient", output_1)
[Link]()
4
Output:
Figure 3.1: Original image
Figure 4.2: 1-Level Image
5
Figure 5.3: 4-Level Image
Figure 6.4: 16-Level Image
Explanation:
For this task, I read a grayscale image and reduced its intensity resolution to 16, 4, and 1 level(s).
For each reduction, pixel values were quantized by integer division and then scaled to the
appropriate output range. The results displayed how decreasing bit depth reduces detail and
introduces banding, visually demonstrating the trade-off between storage and image quality.
6
Task # 03:
For the images given below (also available with the lab handout), apply the connected
component labeling using 4 connectivity and count the total number of objects in the list.
(HINT: In the image given here, the background (black portion) has a numeric value of 1
while the white objects have a numeric value of 255).
Code:
#task03
import cv2
import numpy as np
#making a function to count the unique objects in images
def count_objects(img, image_name):
h, w = [Link]
labels = [Link]((h, w), dtype=int)
next_label = 1
equivalences = {}
# pass 01
for i in range(h):
for j in range(w):
if img[i, j] > 1:
top = labels[i - 1, j] if i > 0 else 0
left = labels[i, j - 1] if j > 0 else 0
#if top and left are both empty
if top == 0 and left == 0:
# new label for the new logic
labels[i, j] = next_label
equivalences[next_label] = next_label
next_label += 1
elif top != 0 and left == 0:
labels[i, j] = top
elif left != 0 and top == 0:
7
labels[i, j] = left
elif top != 0 and left != 0:
# if both neighbors labeled
labels[i, j] = min(top, left)
# add to equivalence table
if top != left:
root_top = top
while equivalences[root_top] !=
root_top:
root_top = equivalences[root_top]
root_left = left
while equivalences[root_left] !=
root_left:
root_left = equivalences[root_left]
smaller = min(root_top, root_left)
equivalences[root_top] = smaller
equivalences[root_left] = smaller
# pass 02
for i in range(h):
for j in range(w):
if labels[i, j] > 0:
# tracing back to the root label
root = labels[i, j]
while equivalences[root] != root:
root = equivalences[root]
labels[i, j] = root
# counting unique objects
unique_labels = [Link](labels)
count = len(unique_labels) - 1 if 0 in unique_labels else
len(unique_labels)
print(f"Total number of objects found in {image_name}:
{count}")
output_img = (labels * (255 // (count if count > 0 else
1))).astype(np.uint8)
[Link](f"Labeled: {image_name}", output_img)
#calling function
image_files = ['x_image.png', 'y_image.png', 'z_image.png']
for file_name in image_files:
img_data = [Link](file_name, cv2.IMREAD_GRAYSCALE)
8
if img_data is not None:
count_objects(img_data, file_name)
[Link]()
[Link]()
Output:
Figure 3.1: Unique object count for each image
Figure 3.2: Labeled image for x_image
9
Figure 3.3: Labeled image for y_image
Figure 3.4: Labeled image for z_image
1
0
Explanation:
For this task, I implemented a two-pass CCA algorithm using 4-way connectivity. The function
processes binary images, assigns temporary labels, resolves equivalences, and re-labels
components with their root identifiers. The final count of unique objects is displayed, and a labeled
output image is shown where each object is colored distinctly based on its label.
Conclusion:
This lab successfully achieved its objectives by providing hands-on experience with intensity
resolution reduction and connected component analysis. Through task completion, I learned how
reducing bit depth affects image quality and how CCA can detect and label objects in binary
images. The implementation of distance maps, intensity quantization, and two-pass labeling
strengthened my understanding of pixel-based operations and their applications in computer
vision. The tasks demonstrated practical skills in image preprocessing and object analysis,
forming a solid foundation for more advanced image segmentation techniques.
1
1