Spaces:
Sleeping
Sleeping
Update cv_functions/functions.py
Browse files- cv_functions/functions.py +264 -0
cv_functions/functions.py
CHANGED
@@ -0,0 +1,264 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import cv2
|
2 |
+
import numpy as np
|
3 |
+
import os
|
4 |
+
|
5 |
+
# Load Haar Cascades for face and object detection
|
6 |
+
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
|
7 |
+
car_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_car.xml')
|
8 |
+
|
9 |
+
# Helper function to convert PIL to OpenCV
|
10 |
+
def pil_to_cv2(image):
|
11 |
+
return cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR)
|
12 |
+
|
13 |
+
# Helper function to convert OpenCV to PIL
|
14 |
+
def cv2_to_pil(image):
|
15 |
+
return cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
|
16 |
+
|
17 |
+
# 1. Image and Video I/O
|
18 |
+
def image_video_io(image=None, video=None):
|
19 |
+
outputs = []
|
20 |
+
if image is not None:
|
21 |
+
img = pil_to_cv2(image)
|
22 |
+
outputs.append(cv2_to_pil(img))
|
23 |
+
if video is not None:
|
24 |
+
cap = cv2.VideoCapture(video)
|
25 |
+
ret, frame = cap.read()
|
26 |
+
if ret:
|
27 |
+
outputs.append(cv2_to_pil(frame))
|
28 |
+
cap.release()
|
29 |
+
return outputs
|
30 |
+
|
31 |
+
# 2. Color Space Conversion
|
32 |
+
def color_space_conversion(image, color_space):
|
33 |
+
img = pil_to_cv2(image)
|
34 |
+
if color_space == "HSV":
|
35 |
+
output = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
|
36 |
+
elif color_space == "LAB":
|
37 |
+
output = cv2.cvtColor(img, cv2.COLOR_BGR2LAB)
|
38 |
+
else:
|
39 |
+
output = img
|
40 |
+
return cv2_to_pil(output)
|
41 |
+
|
42 |
+
# 3. Image Resizing and Cropping
|
43 |
+
def resize_crop(image, scale, crop_x, crop_y, crop_w, crop_h):
|
44 |
+
img = pil_to_cv2(image)
|
45 |
+
h, w = img.shape[:2]
|
46 |
+
new_w, new_h = int(w * scale), int(h * scale)
|
47 |
+
resized = cv2.resize(img, (new_w, new_h))
|
48 |
+
crop_x, crop_y, crop_w, crop_h = int(crop_x * w), int(crop_y * h), int(crop_w * w), int(crop_h * h)
|
49 |
+
cropped = img[crop_y:crop_y+crop_h, crop_x:crop_x+crop_w]
|
50 |
+
return [cv2_to_pil(resized), cv2_to_pil(cropped)]
|
51 |
+
|
52 |
+
# 4. Geometric Transformations
|
53 |
+
def geometric_transform(image, angle, tx, ty):
|
54 |
+
img = pil_to_cv2(image)
|
55 |
+
h, w = img.shape[:2]
|
56 |
+
center = (w // 2, h // 2)
|
57 |
+
M = cv2.getRotationMatrix2D(center, angle, 1.0)
|
58 |
+
M[:, 2] += [tx, ty]
|
59 |
+
transformed = cv2.warpAffine(img, M, (w, h))
|
60 |
+
return cv2_to_pil(transformed)
|
61 |
+
|
62 |
+
# 5. Image Thresholding
|
63 |
+
def thresholding(image, thresh_type, thresh_value, block_size, C):
|
64 |
+
img = pil_to_cv2(image)
|
65 |
+
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
|
66 |
+
if thresh_type == "Global":
|
67 |
+
_, thresh = cv2.threshold(gray, thresh_value, 255, cv2.THRESH_BINARY)
|
68 |
+
else:
|
69 |
+
thresh = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, block_size, C)
|
70 |
+
return cv2_to_pil(thresh)
|
71 |
+
|
72 |
+
# 6. Edge Detection
|
73 |
+
def edge_detection(image, edge_type, canny_t1, canny_t2):
|
74 |
+
img = pil_to_cv2(image)
|
75 |
+
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
|
76 |
+
if edge_type == "Canny":
|
77 |
+
edges = cv2.Canny(gray, canny_t1, canny_t2)
|
78 |
+
elif edge_type == "Sobel":
|
79 |
+
sobelx = cv2.Sobel(gray, cv2.CV_64F, 1, 0, ksize=5)
|
80 |
+
sobely = cv2.Sobel(gray, cv2.CV_64F, 0, 1, ksize=5)
|
81 |
+
edges = cv2.magnitude(sobelx, sobely).astype(np.uint8)
|
82 |
+
else: # Laplacian
|
83 |
+
edges = cv2.Laplacian(gray, cv2.CV_64F).astype(np.uint8)
|
84 |
+
return cv2_to_pil(edges)
|
85 |
+
|
86 |
+
# 7. Image Filtering
|
87 |
+
def image_filtering(image, filter_type, kernel_size):
|
88 |
+
img = pil_to_cv2(image)
|
89 |
+
kernel_size = int(kernel_size) | 1
|
90 |
+
if filter_type == "Gaussian":
|
91 |
+
filtered = cv2.GaussianBlur(img, (kernel_size, kernel_size), 0)
|
92 |
+
else: # Median
|
93 |
+
filtered = cv2.medianBlur(img, kernel_size)
|
94 |
+
return cv2_to_pil(filtered)
|
95 |
+
|
96 |
+
# 8. Contour Detection
|
97 |
+
def contour_detection(image):
|
98 |
+
img = pil_to_cv2(image)
|
99 |
+
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
|
100 |
+
_, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
|
101 |
+
contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
|
102 |
+
output = img.copy()
|
103 |
+
cv2.drawContours(output, contours, -1, (0, 255, 0), 2)
|
104 |
+
return cv2_to_pil(output)
|
105 |
+
|
106 |
+
# 9. Feature Detection (ORB)
|
107 |
+
def feature_detection(image):
|
108 |
+
img = pil_to_cv2(image)
|
109 |
+
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
|
110 |
+
orb = cv2.ORB_create()
|
111 |
+
keypoints, _ = orb.detectAndCompute(gray, None)
|
112 |
+
output = cv2.drawKeypoints(img, keypoints, None, color=(0, 255, 0), flags=0)
|
113 |
+
return cv2_to_pil(output)
|
114 |
+
|
115 |
+
# 10. Object Detection (Haar Cascade for cars)
|
116 |
+
def object_detection(image):
|
117 |
+
img = pil_to_cv2(image)
|
118 |
+
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
|
119 |
+
cars = car_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))
|
120 |
+
output = img.copy()
|
121 |
+
for (x, y, w, h) in cars:
|
122 |
+
cv2.rectangle(output, (x, y), (x+w, y+h), (0, 255, 0), 2)
|
123 |
+
return cv2_to_pil(output)
|
124 |
+
|
125 |
+
# 11. Face Detection
|
126 |
+
def face_detection(image):
|
127 |
+
img = pil_to_cv2(image)
|
128 |
+
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
|
129 |
+
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))
|
130 |
+
output = img.copy()
|
131 |
+
for (x, y, w, h) in faces:
|
132 |
+
cv2.rectangle(output, (x, y), (x+w, y+h), (0, 255, 0), 2)
|
133 |
+
return cv2_to_pil(output)
|
134 |
+
|
135 |
+
# 12. Image Segmentation (GrabCut)
|
136 |
+
def image_segmentation(image):
|
137 |
+
img = pil_to_cv2(image)
|
138 |
+
mask = np.zeros(img.shape[:2], np.uint8)
|
139 |
+
bgdModel = np.zeros((1, 65), np.float64)
|
140 |
+
fgdModel = np.zeros((1, 65), np.float64)
|
141 |
+
rect = (50, 50, img.shape[1]-50, img.shape[0]-50)
|
142 |
+
cv2.grabCut(img, mask, rect, bgdModel, fgdModel, 5, cv2.GC_INIT_WITH_RECT)
|
143 |
+
mask2 = np.where((mask == 2) | (mask == 0), 0, 1).astype('uint8')
|
144 |
+
output = img * mask2[:, :, np.newaxis]
|
145 |
+
return cv2_to_pil(output)
|
146 |
+
|
147 |
+
# 13. Motion Analysis (Optical Flow)
|
148 |
+
def optical_flow(video):
|
149 |
+
cap = cv2.VideoCapture(video)
|
150 |
+
ret, frame1 = cap.read()
|
151 |
+
if not ret:
|
152 |
+
cap.release()
|
153 |
+
return None
|
154 |
+
prvs = cv2.cvtColor(frame1, cv2.COLOR_BGR2GRAY)
|
155 |
+
hsv = np.zeros_like(frame1)
|
156 |
+
hsv[..., 1] = 255
|
157 |
+
ret, frame2 = cap.read()
|
158 |
+
if not ret:
|
159 |
+
cap.release()
|
160 |
+
return cv2_to_pil(frame1)
|
161 |
+
next = cv2.cvtColor(frame2, cv2.COLOR_BGR2GRAY)
|
162 |
+
flow = cv2.calcOpticalFlowFarneback(prvs, next, None, 0.5, 3, 15, 3, 5, 1.2, 0)
|
163 |
+
mag, ang = cv2.cartToPolar(flow[..., 0], flow[..., 1])
|
164 |
+
hsv[..., 0] = ang * 180 / np.pi / 2
|
165 |
+
hsv[..., 2] = cv2.normalize(mag, None, 0, 255, cv2.NORM_MINMAX)
|
166 |
+
output = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)
|
167 |
+
cap.release()
|
168 |
+
return cv2_to_pil(output)
|
169 |
+
|
170 |
+
# 14. Camera Calibration (Simplified)
|
171 |
+
def camera_calibration(image):
|
172 |
+
img = pil_to_cv2(image)
|
173 |
+
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
|
174 |
+
chessboard_size = (9, 6)
|
175 |
+
ret, corners = cv2.findChessboardCorners(gray, chessboard_size, None)
|
176 |
+
output = img.copy()
|
177 |
+
if ret:
|
178 |
+
cv2.drawChessboardCorners(output, chessboard_size, corners, ret)
|
179 |
+
return cv2_to_pil(output)
|
180 |
+
|
181 |
+
# 15. Stereo Vision (Simplified Disparity Map)
|
182 |
+
def stereo_vision(image):
|
183 |
+
img = pil_to_cv2(image)
|
184 |
+
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
|
185 |
+
stereo = cv2.StereoBM_create(numDisparities=16, blockSize=15)
|
186 |
+
disparity = stereo.compute(gray, gray) # Simplified: using same image
|
187 |
+
disparity = cv2.normalize(disparity, None, 0, 255, cv2.NORM_MINMAX).astype(np.uint8)
|
188 |
+
return cv2_to_pil(disparity)
|
189 |
+
|
190 |
+
# 16. Background Subtraction
|
191 |
+
def background_subtraction(video):
|
192 |
+
cap = cv2.VideoCapture(video)
|
193 |
+
fgbg = cv2.createBackgroundSubtractorMOG2()
|
194 |
+
ret, frame = cap.read()
|
195 |
+
if not ret:
|
196 |
+
cap.release()
|
197 |
+
return None
|
198 |
+
fgmask = fgbg.apply(frame)
|
199 |
+
output = cv2.cvtColor(fgmask, cv2.COLOR_GRAY2BGR)
|
200 |
+
cap.release()
|
201 |
+
return cv2_to_pil(output)
|
202 |
+
|
203 |
+
# 17. Image Stitching
|
204 |
+
def image_stitching(image1, image2):
|
205 |
+
img1 = pil_to_cv2(image1)
|
206 |
+
img2 = pil_to_cv2(image2)
|
207 |
+
gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
|
208 |
+
gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
|
209 |
+
orb = cv2.ORB_create()
|
210 |
+
kp1, des1 = orb.detectAndCompute(gray1, None)
|
211 |
+
kp2, des2 = orb.detectAndCompute(gray2, None)
|
212 |
+
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
|
213 |
+
matches = bf.match(des1, des2)
|
214 |
+
matches = sorted(matches, key=lambda x: x.distance)
|
215 |
+
good_matches = matches[:10]
|
216 |
+
src_pts = np.float32([kp1[m.queryIdx].pt for m in good_matches]).reshape(-1, 1, 2)
|
217 |
+
dst_pts = np.float32([kp2[m.trainIdx].pt for m in good_matches]).reshape(-1, 1, 2)
|
218 |
+
M, _ = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0)
|
219 |
+
h, w = img1.shape[:2]
|
220 |
+
result = cv2.warpPerspective(img2, M, (w * 2, h))
|
221 |
+
result[0:h, 0:w] = img1
|
222 |
+
return cv2_to_pil(result)
|
223 |
+
|
224 |
+
# 18. Machine Learning (K-Means)
|
225 |
+
def kmeans_clustering(image, k):
|
226 |
+
img = pil_to_cv2(image)
|
227 |
+
Z = img.reshape((-1, 3))
|
228 |
+
Z = np.float32(Z)
|
229 |
+
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
|
230 |
+
_, label, center = cv2.kmeans(Z, k, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS)
|
231 |
+
center = np.uint8(center)
|
232 |
+
res = center[label.flatten()]
|
233 |
+
output = res.reshape(img.shape)
|
234 |
+
return cv2_to_pil(output)
|
235 |
+
|
236 |
+
# 19. Deep Learning (MobileNet SSD)
|
237 |
+
def deep_learning(image, prototxt_file, model_file):
|
238 |
+
if prototxt_file is None or model_file is None:
|
239 |
+
return None # Model files must be uploaded
|
240 |
+
img = pil_to_cv2(image)
|
241 |
+
net = cv2.dnn.readNetFromCaffe(prototxt_file.file.name, model_file.file.name)
|
242 |
+
blob = cv2.dnn.blobFromImage(cv2.resize(img, (300, 300)), 0.007843, (300, 300), 127.5)
|
243 |
+
net.setInput(blob)
|
244 |
+
detections = net.forward()
|
245 |
+
output = img.copy()
|
246 |
+
for i in range(detections.shape[2]):
|
247 |
+
confidence = detections[0, 0, i, 2]
|
248 |
+
if confidence > 0.5:
|
249 |
+
box = detections[0, 0, i, 3:7] * np.array([img.shape[1], img.shape[0], img.shape[1], img.shape[0]])
|
250 |
+
(startX, startY, endX, endY) = box.astype("int")
|
251 |
+
cv2.rectangle(output, (startX, startY), (endX, endY), (0, 255, 0), 2)
|
252 |
+
return cv2_to_pil(output)
|
253 |
+
|
254 |
+
# 20. Drawing and Text
|
255 |
+
def drawing_text(image, shape, text):
|
256 |
+
img = pil_to_cv2(image)
|
257 |
+
output = img.copy()
|
258 |
+
h, w = img.shape[:2]
|
259 |
+
if shape == "Rectangle":
|
260 |
+
cv2.rectangle(output, (50, 50), (w-50, h-50), (0, 255, 0), 2)
|
261 |
+
elif shape == "Circle":
|
262 |
+
cv2.circle(output, (w//2, h//2), 50, (0, 255, 0), 2)
|
263 |
+
cv2.putText(output, text, (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 2)
|
264 |
+
return cv2_to_pil(output)
|