Posted on
Artificial Intelligence

Artificial Intelligence Edge Computing Projects

Author
  • User
    linuxbash
    Posts by this author
    Posts by this author

AI at the Edge: 3 Linux-Friendly Projects You Can Build This Weekend

Edge AI isn’t just a buzzword—it’s how you cut cloud costs, reduce latency to milliseconds, and keep sensitive data on-site. If you’ve got a Linux box and Bash, you already have what you need to start. This guide walks you through three practical Artificial Intelligence edge computing projects you can build with open tools, plus why they matter and how to install everything cleanly on apt, dnf, and zypper systems.

Why edge AI is worth your time

  • Lower latency: Inference on-device avoids round trips to the cloud.

  • Privacy and compliance: Keep audio/video/sensor data local.

  • Cost control: Fewer cloud inference calls = smaller bills.

  • Resilience: Works even if your internet or cloud provider has issues.

  • Linux loves it: Commodity hardware + open runtimes (ONNX Runtime, TFLite) = fast, repeatable builds.


Prerequisites (Linux packages and Python env)

Install base tools and audio/MQTT utilities:

For apt (Ubuntu/Debian):

sudo apt update
sudo apt install -y python3 python3-venv python3-pip git ffmpeg libportaudio2 portaudio19-dev mosquitto-clients unzip

For dnf (Fedora/RHEL/CentOS Stream):

sudo dnf install -y python3 python3-venv python3-pip git ffmpeg portaudio portaudio-devel mosquitto-clients unzip

For zypper (openSUSE):

sudo zypper refresh
sudo zypper install -y python3 python3-venv python3-pip git ffmpeg portaudio portaudio-devel mosquitto-clients unzip

Create a per-project Python virtual environment (recommended):

python3 -m venv ~/edge-ai-venv
source ~/edge-ai-venv/bin/activate
python -m pip install --upgrade pip

Note: When you see source ~/edge-ai-venv/bin/activate below, use it if your shell isn’t already in that venv.


Project 1: Real-time image classification with ONNX Runtime (CPU or GPU)

Goal: Run a lightweight MobileNetV2 ONNX model on a webcam feed, on-device.

Why it’s edge-worthy: Fast, low-power inference works on nearly any Linux box and can be extended to detect safety gear, sort items, or route camera traffic.

1) Install Python dependencies:

source ~/edge-ai-venv/bin/activate
pip install onnxruntime opencv-python numpy requests
# Optional (NVIDIA CUDA systems): pip install onnxruntime-gpu

2) Get a pre-trained model and labels:

mkdir -p ~/edge-ai/models && cd ~/edge-ai/models
curl -L -o mobilenetv2-7.onnx \
  https://github.com/onnx/models/raw/main/vision/classification/mobilenet/model/mobilenetv2-7.onnx
curl -L -o imagenet-simple-labels.json \
  https://raw.githubusercontent.com/anishathalye/imagenet-simple-labels/master/imagenet-simple-labels.json

3) Create a minimal classifier script:

cat > ~/edge-ai/mobilenet_cam.py << 'PY'
import json, cv2, numpy as np, onnxruntime as ort, time

labels = json.load(open("models/imagenet-simple-labels.json"))
sess = ort.InferenceSession("models/mobilenetv2-7.onnx", providers=["CPUExecutionProvider"])
input_name = sess.get_inputs()[0].name

cap = cv2.VideoCapture(0)
if not cap.isOpened(): raise SystemExit("No webcam found")

def preprocess(frame):
    img = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    img = cv2.resize(img, (224, 224), interpolation=cv2.INTER_LINEAR)
    x = img.astype(np.float32) / 255.0
    x = np.transpose(x, (2, 0, 1))  # HWC -> CHW
    x = np.expand_dims(x, 0)        # NCHW
    return x

while True:
    ok, frame = cap.read()
    if not ok: break
    x = preprocess(frame)
    logits = sess.run(None, {input_name: x})[0][0]
    probs = np.exp(logits) / np.sum(np.exp(logits))
    top_id = int(np.argmax(probs))
    lbl = labels[top_id] if top_id < len(labels) else "unknown"
    conf = float(probs[top_id])

    cv2.putText(frame, f"{lbl} ({conf:.2f})", (10, 30),
                cv2.FONT_HERSHEY_SIMPLEX, 1, (0,255,0), 2)
    cv2.imshow("Edge AI - MobileNetV2", frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()
PY

4) Run it:

cd ~/edge-ai
python mobilenet_cam.py

Tip: For better throughput on CPUs with AVX2, try pip install openvino-dev and use OpenVINO’s runtime for model optimization. On NVIDIA GPUs, onnxruntime-gpu may help if CUDA is installed.


Project 2: Local wake-word detection with Vosk (no cloud)

Goal: Detect a keyword (e.g., “computer”) offline using local speech recognition.

Why it’s edge-worthy: Privacy-first voice UX without sending audio to the cloud.

1) Install Python dependencies:

source ~/edge-ai-venv/bin/activate
pip install vosk sounddevice

2) Download a small English model:

mkdir -p ~/edge-ai/vosk && cd ~/edge-ai/vosk
curl -L -o vosk-model-small-en-us-0.15.zip \
  https://alphacephei.com/vosk/models/vosk-model-small-en-us-0.15.zip
unzip -q vosk-model-small-en-us-0.15.zip
mv vosk-model-small-en-us-0.15 model

3) Create the listener:

cat > ~/edge-ai/wake_word.py << 'PY'
import json, os, queue, sys
import sounddevice as sd
from vosk import Model, KaldiRecognizer

MODEL_DIR = os.path.join(os.path.dirname(__file__), "vosk", "model")
WAKE_WORD = os.environ.get("WAKE_WORD", "computer").lower()
RATE = 16000

if not os.path.isdir(MODEL_DIR):
    sys.exit("Vosk model not found. Check ~/edge-ai/vosk/model")

model = Model(MODEL_DIR)
rec = KaldiRecognizer(model, RATE)
rec.SetWords(True)

q = queue.Queue()

def audio_cb(indata, frames, time, status):
    if status: print(status, file=sys.stderr)
    q.put(bytes(indata))

with sd.RawInputStream(samplerate=RATE, blocksize=8000, dtype='int16',
                       channels=1, callback=audio_cb):
    print(f"Listening for '{WAKE_WORD}' (Ctrl+C to quit)...")
    try:
        while True:
            data = q.get()
            if rec.AcceptWaveform(data):
                res = json.loads(rec.Result())
                text = res.get("text", "").lower()
                if WAKE_WORD in text:
                    print(f"[{WAKE_WORD}] detected!")
            else:
                # Partial results could be inspected here if desired.
                pass
    except KeyboardInterrupt:
        print("\nStopped.")
PY

4) Run it:

cd ~/edge-ai
WAKE_WORD=computer python wake_word.py

If you see “Error opening InputStream,” verify your microphone and PortAudio installation. On PulseAudio/PipeWire systems, select the correct device with sounddevice.default.device or by setting the PULSE_SINK/SOURCE environment variables.


Project 3: Sensor anomaly alerts over MQTT (lightweight and fast)

Goal: Flag unusual sensor readings locally and publish alerts—no cloud round trip.

Why it’s edge-worthy: Real-time detection near the data source reduces bandwidth and increases reliability.

1) Install Python dependencies:

source ~/edge-ai-venv/bin/activate
pip install numpy paho-mqtt

2) Create the anomaly detector (rolling mean/std with 3-sigma rule):

cat > ~/edge-ai/anomaly_mqtt.py << 'PY'
import os, time, json
from collections import deque
import numpy as np
import paho.mqtt.client as mqtt

BROKER = os.environ.get("MQTT_BROKER", "localhost")
IN_TOPIC = os.environ.get("MQTT_IN", "sensors/temperature")
OUT_TOPIC = os.environ.get("MQTT_OUT", "alerts/temperature")
WINDOW = int(os.environ.get("WINDOW", "60"))
THRESH_K = float(os.environ.get("THRESH_K", "3.0"))

buf = deque(maxlen=WINDOW)

def on_connect(client, userdata, flags, rc):
    print("Connected" if rc == 0 else f"Connect failed: {rc}")
    client.subscribe(IN_TOPIC)

def on_message(client, userdata, msg):
    try:
        val = float(msg.payload.decode().strip())
    except Exception:
        return
    buf.append(val)
    if len(buf) >= 10:
        arr = np.array(buf, dtype=float)
        mu, sd = float(arr.mean()), float(arr.std(ddof=1)) if len(arr)>1 else (arr[0], 0.0)
        if sd > 0 and abs(val - mu) > THRESH_K * sd:
            alert = {"value": val, "mean": mu, "std": sd, "topic": IN_TOPIC, "ts": time.time()}
            client.publish(OUT_TOPIC, json.dumps(alert))
            print("Anomaly:", alert)
        else:
            print("OK:", val)
    else:
        print("Warming up:", val)

client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.connect(BROKER, 1883, 60)
client.loop_forever()
PY

3) Test with simulated data:

  • Start the detector:
cd ~/edge-ai
python anomaly_mqtt.py
  • Publish normal values:
for i in {1..50}; do mosquitto_pub -t sensors/temperature -m $((RANDOM%3 + 22)); sleep 0.2; done
  • Publish an anomaly:
mosquitto_pub -t sensors/temperature -m 45

4) Optional: Run as a systemd service (auto-start on boot):

cat | sudo tee /etc/systemd/system/anomaly-mqtt.service > /dev/null << 'UNIT'
[Unit]
Description=Edge AI MQTT anomaly detector
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=%i
ExecStart=/home/%i/edge-ai-venv/bin/python /home/%i/edge-ai/anomaly_mqtt.py
Restart=on-failure
Environment=MQTT_BROKER=localhost MQTT_IN=sensors/temperature MQTT_OUT=alerts/temperature WINDOW=60 THRESH_K=3.0

[Install]
WantedBy=multi-user.target
UNIT

Enable and start (replace $USER with your username if running as your user):

sudo systemctl enable anomaly-mqtt.service
sudo systemctl start anomaly-mqtt.service
sudo systemctl status anomaly-mqtt.service

Optimization tips (when you’re ready)

  • Quantize for speed: Use smaller models (MobileNet, Tiny variants) and consider INT8 quantization to shrink memory and boost throughput.

  • Choose the right runtime: ONNX Runtime for generality, OpenVINO for Intel CPUs/VPUs, TensorRT for NVIDIA GPUs, TFLite for tiny CPUs/ARM.

  • Batch wisely: For streaming tasks, batch=1 and low-latency pipelines beat large-batch throughput.

  • Containerize: Use Docker/Podman for reproducible deployments and easy rollbacks at the edge.

  • Monitor: Wrap long-running scripts with systemd and log to journald or a local time-series DB.


Conclusion and next steps

You now have three real, working edge AI building blocks:

  • Vision classification from a webcam

  • Offline wake-word detection

  • On-device anomaly alerts for MQTT sensors

Pick one, harden it with systemd or containers, and extend it—swap models, add hardware acceleration, or wire alerts to your ops tools. When you’re ready, combine them into a single edge node that sees, listens, and reacts locally.

If you want a follow-up post on GPU acceleration (ONNXRuntime-GPU, TensorRT) or Intel OpenVINO optimization on CPUs, let me know which hardware you’re targeting.