Spaces:
Runtime error
Runtime error
Commit
•
28f3c74
1
Parent(s):
c630d8d
initial commit. copy of pff-prototype-v1
Browse files- app.py +14 -0
- detector.py +82 -0
- model_densenet_zeros.pkl +3 -0
app.py
ADDED
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import gradio as gr
|
2 |
+
from detector import bat_detector
|
3 |
+
|
4 |
+
def find_bats(input_img):
|
5 |
+
bats, time = bat_detector(input_img)
|
6 |
+
return f"{bats}" + " bats found in " + f"{time:.2f}s"
|
7 |
+
|
8 |
+
iface = gr.Interface(
|
9 |
+
fn=find_bats,
|
10 |
+
inputs=gr.Image(shape=(640, 512)),
|
11 |
+
outputs='text'
|
12 |
+
)
|
13 |
+
|
14 |
+
iface.launch()
|
detector.py
ADDED
@@ -0,0 +1,82 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import cv2 as cv
|
2 |
+
import numpy as np
|
3 |
+
from fastai.vision.all import *
|
4 |
+
import time
|
5 |
+
|
6 |
+
def chop_img(img, step):
|
7 |
+
allImgs = []
|
8 |
+
width, height, i, j = 640, 512, 0, 0
|
9 |
+
for i in range(step):
|
10 |
+
for j in range(step):
|
11 |
+
# crop the image into step*rows and step*columns
|
12 |
+
imgCrop = img[int(0 + height / step * i): int(height / step + height / step * i),
|
13 |
+
int(0 + width / step * j): int(width / step + width / step * j)]
|
14 |
+
imgGray = cv.cvtColor(imgCrop, cv.COLOR_BGR2GRAY)
|
15 |
+
imgResize = cv.resize(imgGray, (640, 512)) # Resize image
|
16 |
+
imgAug = augment(imgResize)
|
17 |
+
allImgs.append((imgResize, imgAug))
|
18 |
+
j += 1
|
19 |
+
i += 1
|
20 |
+
return allImgs
|
21 |
+
|
22 |
+
def augment(img):
|
23 |
+
kernel = np.ones((5, 5), np.uint8)
|
24 |
+
imgBlur = cv.GaussianBlur(img, (5, 5), 0) # apply gaussian blur
|
25 |
+
imgThresh = cv.adaptiveThreshold( # apply adaptive threshold
|
26 |
+
imgBlur, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY_INV, 7, 5)
|
27 |
+
imgDilation = cv.dilate(imgThresh, kernel, iterations=1) # apply dilation to amplify threshold result
|
28 |
+
return imgDilation
|
29 |
+
|
30 |
+
def crop_bat(img, box):
|
31 |
+
x1, y1, x2, y2, x3, y3, x4, y4 = int(box[0][1]), int(box[0][0]), int(box[1][1]), int(box[1][0]), int(box[2][1]), int(box[2][0]), int(box[3][1]), int(box[3][0])
|
32 |
+
|
33 |
+
# Find distance from cx to top_left_x and cy to top_left_y to determine how many pixels the border around the cropped image should be
|
34 |
+
top_left_x, top_left_y, bot_right_x, bot_right_y = min([x1,x2,x3,x4]), min([y1,y2,y3,y4]), max([x1,x2,x3,x4]), max([y1,y2,y3,y4])
|
35 |
+
|
36 |
+
crop_x1 = top_left_x - 10
|
37 |
+
if crop_x1 <= 0:
|
38 |
+
crop_x1 = 1
|
39 |
+
|
40 |
+
crop_x2 = bot_right_x+11
|
41 |
+
if crop_x2 > 512:
|
42 |
+
crop_x2 = 512
|
43 |
+
|
44 |
+
crop_y1 = top_left_y-10
|
45 |
+
if crop_y1 <= 0:
|
46 |
+
crop_y1 = 1
|
47 |
+
|
48 |
+
crop_y2 = bot_right_y+11
|
49 |
+
if crop_y2 > 640:
|
50 |
+
crop_y2 = 640
|
51 |
+
|
52 |
+
bat_crop = img[crop_x1: crop_x2, crop_y1: crop_y2]
|
53 |
+
|
54 |
+
return bat_crop
|
55 |
+
|
56 |
+
def find_bats(allImgs):
|
57 |
+
batDepthMin, batDepthMax = 50, 400
|
58 |
+
cropped_bats = []
|
59 |
+
|
60 |
+
for img in allImgs:
|
61 |
+
blobs = cv.findContours(img[1], cv.RETR_LIST, cv.CHAIN_APPROX_SIMPLE)[-2]
|
62 |
+
cropped_bats.extend([crop_bat(img[0], np.int0(cv.boxPoints(cv.minAreaRect(blob)))) for blob in blobs if batDepthMin < cv.contourArea(blob) < batDepthMax])
|
63 |
+
|
64 |
+
return cropped_bats
|
65 |
+
|
66 |
+
def bat_detector(img):
|
67 |
+
start=time.time()
|
68 |
+
allImgs = chop_img(img, 3)
|
69 |
+
cropped_bats = find_bats(allImgs)
|
70 |
+
|
71 |
+
learn = load_learner("model_densenet_zeros.pkl")
|
72 |
+
|
73 |
+
def predict(bat):
|
74 |
+
with learn.no_bar(), learn.no_logging():
|
75 |
+
start = time.time()
|
76 |
+
_, _, probs = learn.predict(bat)
|
77 |
+
print(f"{time.time()-start:.4f}s")
|
78 |
+
return (tuple(map(lambda x: f"{x:.4f}", probs)))
|
79 |
+
|
80 |
+
filtered_results = filter(lambda x: (x[0] < '0.9' and x[1] > '0.5'), [predict(bat) for bat in cropped_bats]) # x[0] is !bat probability and x[1] is bat probability
|
81 |
+
|
82 |
+
return len(list(filtered_results)), (time.time()-start)
|
model_densenet_zeros.pkl
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:180f4e429006d564a38fc42c4ed4bfa99cbc7bd08a7478a75562b235e8c102a2
|
3 |
+
size 81822355
|