HTTP API Reference
shimeta_camera and shimeta_svp automatically provide HTTP APIs on port 8080 once started.
1. shimeta_camera
GET /api/status
Returns real-time inference status and detection results.
{
"total_frames": 150,
"fps": 18.5,
"infer_ms": 12.3,
"detections": [
{
"class_id": 0,
"label": "person",
"conf": 0.92,
"x1": 100,
"y1": 200,
"x2": 300,
"y2": 400
}
]
}| Field | Type | Description |
|---|---|---|
total_frames | int | Cumulative frame count |
fps | float | Real-time frame rate |
infer_ms | float | Inference time (milliseconds) |
detections | array | Detection results |
detections[].class_id | int | Class ID (0=person, 1=bicycle, ...) |
detections[].label | string | Class name |
detections[].conf | float | Confidence (0-1) |
detections[].x1,y1,x2,y2 | int | Bounding box coordinates |
GET /api/snapshot
Returns current frame JPEG snapshot.
Content-Type: image/jpegGET /stream
MJPEG live video stream.
Content-Type: multipart/x-mixed-replace; boundary=frame2. shimeta_svp
GET /
Returns detection results for the current SVP task. Response format varies by task type.
person / head / car / bike / fireworks
{
"task": "head",
"fps": 22.5,
"total": 300,
"dets": [
{
"class": 4,
"conf": 88,
"x1": 100,
"y1": 200,
"x2": 150,
"y2": 280
}
]
}| Field | Type | Description |
|---|---|---|
task | string | Task name |
fps | float | Real-time frame rate |
total | int | Cumulative frames |
dets[].class | int | Class ID (4=head, 0=person, ...) |
dets[].conf | int | Confidence percentage (0-100) |
dets[].x1,y1,x2,y2 | int | Bounding box coordinates (640×360 space) |
person_kp
Adds kp field (17-point human keypoints) to dets:
{
"task": "person_kp",
"fps": 22.5,
"total": 300,
"dets": [
{
"class": 8,
"conf": 73,
"x1": 100,
"y1": 200,
"x2": 250,
"y2": 350,
"kp": [
[320, 50, 0.9],
[310, 45, 0.8]
]
}
]
}| Field | Description |
|---|---|
kp[][0] | Keypoint X coordinate |
kp[][1] | Keypoint Y coordinate |
kp[][2] | Keypoint confidence (0-1) |
17-point order: nose, left_eye, right_eye, left_ear, right_ear, left_shoulder, right_shoulder, left_elbow, right_elbow, left_wrist, right_wrist, left_hip, right_hip, left_knee, right_knee, left_ankle, right_ankle
face_emo
{
"task": "face_emo",
"fps": 22.5,
"total": 300,
"faces": [
{
"emotion": "SMILE",
"conf": 88,
"x1": 200,
"y1": 100,
"x2": 280,
"y2": 200
}
]
}| emotion Value | Description |
|---|---|
SMILE | Smiling |
NORMAL | Neutral |
UNKNOWN | Unknown |
dms
{
"task": "dms",
"fps": 22.5,
"total": 300,
"dms": [
{
"fatigue": 1,
"phone": 0,
"cigar": 1,
"x1": 150,
"y1": 80,
"x2": 350,
"y2": 320
}
],
"phone_boxes": [{ "x1": 260, "y1": 180, "x2": 290, "y2": 210 }],
"cigar_boxes": [{ "x1": 270, "y1": 160, "x2": 285, "y2": 175 }]
}| Field | Description |
|---|---|
dms[].fatigue | Fatigue flag (0/1, eyes closed or yawning) |
dms[].phone | Phone detection count |
dms[].cigar | Cigarette detection count |
phone_boxes | Phone location boxes |
cigar_boxes | Cigarette location boxes |
3. Python SDK
shimeta_camera Client
"""
ShiMeta Camera Client — single file, copy & use
Usage:
from camera_client import Camera
cam = Camera("192.168.49.10:8080")
for d in cam.detect(): print(d.label, d.conf)
"""
import requests, time
from collections import namedtuple
Detection = namedtuple("Detection",
["class_id","label","conf","x1","y1","x2","y2","center"])
class Camera:
def __init__(self, host, timeout=2.0):
if ":" not in host: host = host + ":8080"
self._base = f"http://{host}"
self._timeout = timeout
def status(self):
"""Full status: frames, fps, infer_ms, det_count"""
return self._get("/api/status")
def detect(self, class_name=None, min_conf=0.0):
"""Detection results, filterable by class name and min confidence"""
j = self._get("/api/status")
result = []
for d in j.get("detections", []):
label = d.get("label") or f"cls_{d.get('class_id',0)}"
conf = float(d.get("conf", 0))
if class_name and label != class_name: continue
if conf < min_conf: continue
x1,y1,x2,y2 = int(d["x1"]),int(d["y1"]),int(d["x2"]),int(d["y2"])
result.append(Detection(d["class_id"],label,conf,x1,y1,x2,y2,
((x1+x2)/2,(y1+y2)/2)))
return result
def snapshot(self, save_path):
"""Save current frame JPEG snapshot"""
r = requests.get(f"{self._base}/api/snapshot", timeout=self._timeout)
with open(save_path, "wb") as f: f.write(r.content)
return save_path
def stream_url(self): return f"{self._base}/stream"
def snapshot_url(self): return f"{self._base}/api/snapshot"
def wait_online(self, timeout=30):
deadline = time.time() + timeout
while time.time() < deadline:
try: self.status(); return True
except: time.sleep(0.5)
return False
def _get(self, path):
r = requests.get(f"{self._base}{path}", timeout=self._timeout)
r.raise_for_status()
return r.json()shimeta_svp Client
class SVP:
def __init__(self, host, timeout=2.0):
if ":" not in host: host = host + ":8080"
self._base = f"http://{host}"
self._timeout = timeout
def status(self):
"""Get SVP task status and detection results"""
return self._get("/")
def detect(self):
"""Return normalized detection list"""
j = self._get("/")
result = []
# Standard detection format
for d in j.get("dets", []):
result.append({
"class": d["class"],
"conf": d["conf"] / 100.0, # Convert to 0-1
"bbox": (d["x1"], d["y1"], d["x2"], d["y2"])
})
# Face recognition
for f in j.get("faces", []):
result.append({
"name": f.get("name", ""),
"sim": f.get("sim", 0),
"emotion": f.get("emotion", ""),
"bbox": (f["x1"], f["y1"], f["x2"], f["y2"])
})
# Driver monitoring
for d in j.get("dms", []):
result.append({
"fatigue": d.get("fatigue", 0),
"phone": d.get("phone", 0),
"cigar": d.get("cigar", 0)
})
return result
def _get(self, path):
r = requests.get(f"{self._base}{path}", timeout=self._timeout)
r.raise_for_status()
return r.json()Usage Examples
# ---- shimeta_camera ----
cam = Camera("192.168.49.10")
cam.wait_online()
# Filter by class
people = cam.detect(class_name="person", min_conf=0.5)
for p in people:
print(f"Person @ ({p.center[0]:.0f}, {p.center[1]:.0f}) conf={p.conf:.0%}")
# All detections (label determined by model's labels.txt, not hardcoded COCO)
all = cam.detect(min_conf=0.3)
for d in all:
print(f"{d.label} conf={d.conf:.2f} box=({d.x1},{d.y1})-({d.x2},{d.y2})")
# Status monitoring
st = cam.status()
print(f"FPS:{st.get('fps',0):.1f} inference:{st.get('infer_ms',0):.1f}ms")
# Save snapshot
cam.snapshot("frame.jpg")
# Stream URL
print(cam.stream_url()) # http://IP:8080/stream
# ---- shimeta_svp ----
svp = SVP("192.168.49.10")
j = svp.status()
task = j.get("task", "")
if "dets" in j: # person/head/car/pet etc.
for d in j["dets"]:
print(f"class={d['class']} conf={d['conf']}% box=({d['x1']},{d['y1']})-({d['x2']},{d['y2']})")
elif "faces" in j: # face_recog / face_emo
for f in j["faces"]:
print(f"{f.get('name','?')}{f.get('emotion','')} sim={f.get('sim',0)}% box=({f['x1']},{f['y1']})-({f['x2']},{f['y2']})")
elif "dms" in j: # dms
for d in j["dms"]:
print(f"fatigue={d['fatigue']} phone={d['phone']} cigar={d['cigar']}")Snapshot Capture
import requests
from PIL import Image
from io import BytesIO
r = requests.get("http://192.168.49.10:8080/api/snapshot")
img = Image.open(BytesIO(r.content))
img.save("frame.jpg")OpenCV Streaming
import cv2
# MJPEG stream (shimeta_camera)
cap = cv2.VideoCapture("http://192.168.49.10:8080/stream")
# RTSP stream (shimeta_svp)
cap = cv2.VideoCapture("rtsp://192.168.49.10:554/livestream/0")
while True:
ret, frame = cap.read()
if ret: cv2.imshow("Camera", frame)
if cv2.waitKey(1) & 0xFF == ord('q'): break4. General Notes
- Label resolution: The
labelfield is provided bylabels.txtinside the model zip; when the server doesn't send a label, the SDK falls back tocls_{id}format. COCO class names are not hardcoded. - Coordinate space: SVP coordinates are 640×360 (output resolution) — scale as needed for display
- Update frequency: Every frame (~22-25fps)
- CORS: Response headers include
Access-Control-Allow-Origin: * - Port: Default 8080, shared by
shimeta_cameraandshimeta_svp— they cannot run simultaneously
