-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcode.py
More file actions
90 lines (80 loc) · 3.35 KB
/
code.py
File metadata and controls
90 lines (80 loc) · 3.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import cv2
import numpy as np
# finding contours and placing a bounding box around the circular region
def findContours(img):
imgContour = np.zeros_like(img)
contours, hierarchy = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
for cnt in contours:
area = cv2.contourArea(cnt)
cv2.drawContours(imgContour, cnt, -1, (255, 0, 0), 1)
peri = cv2.arcLength(cnt, True)
approx = cv2.approxPolyDP(cnt, 0.02 * peri, True)
objCor = len(approx)
x, y, w, h = cv2.boundingRect(approx)
cv2.rectangle(imgContour, (x, y), (x + w, y + h), (255, 0, 0), -1)
return imgContour
# isolating different parts with similar color to a single color
def kmeans_segmentation(image, k):
pixels = image.reshape((-1, 3))
pixels = np.float32(pixels)
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 100, 0.2)
_, labels, centers = cv2.kmeans(pixels, k, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS)
centers = np.uint8(centers)
segmented_image = centers[labels.flatten()]
segmented_image = segmented_image.reshape(image.shape)
return segmented_image
# finding the least frequent pixels with same value
def find_least_frequent_pixels(image):
flat_image = image.flatten()
unique_values, counts = np.unique(flat_image, return_counts=True)
least_frequent_value = unique_values[np.argmin(counts)]
least_frequent_mask = (image == least_frequent_value).astype(np.uint8)
return least_frequent_mask * 255
# turning all the non black pixels to white
def white(img):
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
mat = np.array(img)
for i in range(mat.shape[0]):
for j in range(mat.shape[1]):
if mat[i][j]!=0:
mat[i][j]=255
return mat
# keeping a saturation threshold (works for the sample images but may not work for others)
def increase_saturation(img, s_min = 0, s_max = 255, v_min = 0, v_max = 255, h_min = 0, h_max = 179):
imgHSV = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
lower = np.array([h_min,s_min,v_min])
upper = np.array([h_max,s_max,v_max])
mask = cv2.inRange(imgHSV,lower,upper)
imgResult = cv2.bitwise_and(img,img,mask=mask)
return imgResult
# processing stage
def process(img):
imgt = img.copy()
# locating the circular region
imgt = increase_saturation(imgt,128)
imgt = cv2.cvtColor(imgt, cv2.COLOR_BGR2GRAY)
imgt = cv2.GaussianBlur(imgt, (3, 3), 0)
imgt = cv2.Canny(imgt, 0, 100)
imgt = findContours(imgt)
imgt = cv2.bitwise_and(img,img,mask=imgt)
# applying kmeans segmentation and the masking
imgt = kmeans_segmentation(imgt, 4)
imgt = find_least_frequent_pixels(imgt)
imgt = white(imgt)
imgt = cv2.bitwise_and(img,img,mask=imgt)
return imgt
# input and output
paths = ["..\character-segmentation\Test_images\{}.jpeg".format(i) for i in range(1, 8)]
pic = [None] * 8
for i in range(1, 8):
pic[i] = cv2.imread(paths[i-1])
pic[i] = process(pic[i])
cv2.imwrite(f"..\character-segmentation\segmented_test_images\\result{i}.png", pic[i])
# stitching all the output images together
blank = np.zeros_like(pic[7])
stackedH1 = np.hstack((pic[1], pic[2], pic[3]))
stackedH2 = np.hstack((pic[4], pic[5], pic[6]))
stackedH3 = np.hstack((pic[7], blank, blank))
result = np.vstack((stackedH1, stackedH2, stackedH3))
cv2.imshow("Result", result)
cv2.waitKey(0)