abhishek-gola's picture
onnx models (#12)
e9eb33d
Raw
History Blame Contribute Delete
3.72 kB
import argparse
import glob
import os
import cv2 as cv
import numpy as np
here = os.path.dirname(os.path.abspath(__file__))
sz = 300
layers = [
(30, 60, [2], 8, 38),
(60, 111, [2, 3], 16, 19),
(111, 162, [2, 3], 32, 10),
(162, 213, [2, 3], 64, 5),
(213, 264, [2], 100, 5),
(264, 315, [2], 300, 5),
]
var = [0.1, 0.1, 0.2, 0.2]
def build_priors():
p = []
for mn, mx, ars, step, fm in layers:
ratios = [1.0]
for a in ars:
ratios += [a, 1.0 / a]
for y in range(fm):
for x in range(fm):
cx = (x + 0.5) * step
cy = (y + 0.5) * step
boxes = [(mn, mn), ((mn * mx) ** 0.5, (mn * mx) ** 0.5)]
for a in ratios[1:]:
boxes.append((mn * a ** 0.5, mn / a ** 0.5))
for bw, bh in boxes:
p.append([cx, cy, bw, bh])
return np.array(p, np.float32)
def default_model():
files = [f for f in glob.glob(os.path.join(here, "*.onnx")) if "known_good" not in os.path.basename(f)]
return files[0] if files else os.path.join(here, "opencv_face_detector_uint8.onnx")
def main():
parser = argparse.ArgumentParser(description="OpenCV SSD face detector (ONNX) demo")
parser.add_argument("--model", default=default_model())
parser.add_argument("--image", default=os.path.join(here, "example_outputs", "input_image.png"))
parser.add_argument("--output", default=os.path.join(here, "example_outputs", "output_image.png"))
parser.add_argument("--conf", type=float, default=0.4)
args = parser.parse_args()
img = cv.imread(args.image)
if img is None:
raise SystemExit("could not read image: %s" % args.image)
inp = cv.resize(img, (sz, sz)).astype(np.float32) - np.array([104.0, 177.0, 123.0], np.float32)
net = cv.dnn.readNetFromONNX(args.model)
onames = net.getUnconnectedOutLayersNames()
net.setInput(inp[None])
res = net.forward(onames)
loc = res[[i for i, n in enumerate(onames) if "mbox_loc" in n][0]].reshape(-1, 4)
conf = res[[i for i, n in enumerate(onames) if "mbox_conf" in n][0]].reshape(-1, 2)
priors = build_priors()
pcx = priors[:, 0] / sz
pcy = priors[:, 1] / sz
pw = priors[:, 2] / sz
ph = priors[:, 3] / sz
e = np.exp(conf - conf.max(1, keepdims=True))
sm = e / e.sum(1, keepdims=True)
scores = sm[:, 1]
cx = pcx + loc[:, 0] * var[0] * pw
cy = pcy + loc[:, 1] * var[1] * ph
bw = pw * np.exp(loc[:, 2] * var[2])
bh = ph * np.exp(loc[:, 3] * var[3])
boxes = np.stack([cx - bw / 2, cy - bh / 2, cx + bw / 2, cy + bh / 2], 1)
keep = scores > args.conf
boxes = boxes[keep]
scores = scores[keep]
order = scores.argsort()[::-1]
pick = []
while order.size:
i = order[0]
pick.append(i)
xx1 = np.maximum(boxes[i, 0], boxes[order[1:], 0])
yy1 = np.maximum(boxes[i, 1], boxes[order[1:], 1])
xx2 = np.minimum(boxes[i, 2], boxes[order[1:], 2])
yy2 = np.minimum(boxes[i, 3], boxes[order[1:], 3])
inter = np.maximum(0, xx2 - xx1) * np.maximum(0, yy2 - yy1)
ai = (boxes[i, 2] - boxes[i, 0]) * (boxes[i, 3] - boxes[i, 1])
aj = (boxes[order[1:], 2] - boxes[order[1:], 0]) * (boxes[order[1:], 3] - boxes[order[1:], 1])
iou = inter / (ai + aj - inter + 1e-9)
order = order[1:][iou <= 0.3]
h, w = img.shape[:2]
for i in pick:
x1, y1, x2, y2 = boxes[i]
cv.rectangle(img, (int(x1 * w), int(y1 * h)), (int(x2 * w), int(y2 * h)), (0, 255, 0), 2)
cv.imwrite(args.output, img)
print("opencv_face_detector_uint8", len(pick), "faces")
if __name__ == "__main__":
main()