Sample usage.

This commit is contained in:
cosmin 2024-10-23 20:39:10 +03:00
parent d951e2369d
commit b485d4e838
6 changed files with 516 additions and 0 deletions

175
OpenCV-4-10-0-adapted.sh Executable file
View File

@ -0,0 +1,175 @@
#!/bin/bash
set -e
install_opencv () {
# Check if the file /proc/device-tree/model exists
if [ -e "/proc/device-tree/model" ]; then
# Read the model information from /proc/device-tree/model and remove null bytes
model=$(tr -d '\0' < /proc/device-tree/model)
# Check if the model information contains "Jetson Nano Orion"
echo ""
if [[ $model == *"Orin"* ]]; then
echo "Detecting a Jetson Nano Orin."
NO_JOB=4
ARCH=8.7
PTX="sm_87"
elif [[ $model == *"Jetson Nano"* ]]; then
echo "Detecting a regular Jetson Nano."
ARCH=5.3
PTX="sm_53"
# Use "-j 4" only swap space is larger than 5.5GB
FREE_MEM="$(free -m | awk '/^Swap/ {print $2}')"
if [[ "FREE_MEM" -gt "5500" ]]; then
NO_JOB=4
else
echo "Due to limited swap, make only uses 1 core"
NO_JOB=1
fi
else
echo "Unable to determine the Jetson Nano model."
exit 1
fi
echo ""
else
echo "Error: /proc/device-tree/model not found. Are you sure this is a Jetson Nano?"
exit 1
fi
echo "Installing OpenCV 4.9.0 on your Nano"
echo "It will take 3.5 hours !"
# reveal the CUDA location
cd ~
sudo sh -c "echo '/usr/local/cuda/lib64' >> /etc/ld.so.conf.d/nvidia-tegra.conf"
sudo ldconfig
# install the Jetson Nano dependencies first
if [[ $model == *"Jetson Nano"* ]]; then
sudo apt-get install -y build-essential git unzip pkg-config zlib1g-dev
sudo apt-get install -y python3-dev python3-numpy python3-pip
sudo apt-get install -y gstreamer1.0-tools libgstreamer-plugins-base1.0-dev
sudo apt-get install -y libgstreamer-plugins-good1.0-dev
sudo apt-get install -y libtbb2 libgtk-3-dev v4l2ucp libxine2-dev
fi
if [ -f /etc/os-release ]; then
# Source the /etc/os-release file to get variables
. /etc/os-release
# Extract the major version number from VERSION_ID
VERSION_MAJOR=$(echo "$VERSION_ID" | cut -d'.' -f1)
# Check if the extracted major version is 22 or earlier
if [ "$VERSION_MAJOR" = "22" ]; then
sudo apt-get install -y libswresample-dev libdc1394-dev
else
sudo apt-get install -y libavresample-dev libdc1394-22-dev
fi
else
sudo apt-get install -y libavresample-dev libdc1394-22-dev
fi
# install the common dependencies
sudo apt-get install -y cmake
sudo apt-get install -y libjpeg-dev libjpeg8-dev libjpeg-turbo8-dev
sudo apt-get install -y libpng-dev libtiff-dev libglew-dev
sudo apt-get install -y libavcodec-dev libavformat-dev libswscale-dev
sudo apt-get install -y libgtk2.0-dev libgtk-3-dev libcanberra-gtk*
sudo apt-get install -y libxvidcore-dev libx264-dev
sudo apt-get install -y libtbb-dev libxine2-dev
sudo apt-get install -y libv4l-dev v4l-utils qv4l2
sudo apt-get install -y libtesseract-dev libpostproc-dev
sudo apt-get install -y libvorbis-dev
sudo apt-get install -y libfaac-dev libmp3lame-dev libtheora-dev
sudo apt-get install -y libopencore-amrnb-dev libopencore-amrwb-dev
sudo apt-get install -y libopenblas-dev libatlas-base-dev libblas-dev
sudo apt-get install -y liblapack-dev liblapacke-dev libeigen3-dev gfortran
sudo apt-get install -y libhdf5-dev libprotobuf-dev protobuf-compiler
sudo apt-get install -y libgoogle-glog-dev libgflags-dev
# remove old versions or previous builds
cd ~
sudo rm -rf opencv*
# download the latest version
git clone --depth=1 https://github.com/opencv/opencv.git
git clone --depth=1 https://github.com/opencv/opencv_contrib.git
# set install dir
cd ~/opencv
mkdir build
cd build
# run cmake
cmake -D CMAKE_BUILD_TYPE=RELEASE \
-D CMAKE_INSTALL_PREFIX=/usr \
-D OPENCV_EXTRA_MODULES_PATH=~/opencv_contrib/modules \
-D EIGEN_INCLUDE_PATH=/usr/include/eigen3 \
-D WITH_OPENCL=OFF \
-D CUDA_ARCH_BIN=${ARCH} \
-D CUDA_ARCH_PTX=${PTX} \
-D WITH_CUDA=ON \
-D WITH_CUDNN=ON \
-D WITH_CUBLAS=ON \
-D ENABLE_FAST_MATH=ON \
-D CUDA_FAST_MATH=ON \
-D OPENCV_DNN_CUDA=ON \
-D ENABLE_NEON=ON \
-D WITH_QT=OFF \
-D WITH_OPENMP=ON \
-D BUILD_TIFF=ON \
-D WITH_FFMPEG=ON \
-D WITH_GSTREAMER=ON \
-D WITH_TBB=ON \
-D BUILD_TBB=ON \
-D BUILD_TESTS=OFF \
-D WITH_EIGEN=ON \
-D WITH_V4L=ON \
-D WITH_LIBV4L=ON \
-D WITH_PROTOBUF=ON \
-D INSTALL_C_EXAMPLES=OFF \
-D INSTALL_PYTHON_EXAMPLES=OFF \
-D PYTHON3_EXECUTABLE=$(which python3) \
-D PYTHON3_INCLUDE_DIR=$(python3 -c "from distutils.sysconfig import get_python_inc; print(get_python_inc())") \
-D PYTHON3_LIBRARY=$(python3 -c "import distutils.sysconfig as sysconfig; print(sysconfig.get_config_var('LIBDIR'))") \
-D PYTHON3_PACKAGES_PATH=$(python3 -c "import site; print(site.getsitepackages()[0])") \
-D OPENCV_GENERATE_PKGCONFIG=ON \
-D BUILD_EXAMPLES=OFF \
-D CMAKE_CXX_FLAGS="-march=native -mtune=native" \
-D CMAKE_C_FLAGS="-march=native -mtune=native" ..
make -j ${NO_JOB}
directory="/usr/include/opencv4/opencv2"
if [ -d "$directory" ]; then
# Directory exists, so delete it
sudo rm -rf "$directory"
fi
sudo make install
sudo ldconfig
# cleaning (frees 320 MB)
make clean
sudo apt-get update
echo "Congratulations!"
echo "You've successfully installed OpenCV 4.9.0 on your Nano with Python 3 bindings."
}
cd ~
if [ -d ~/opencv/build ]; then
echo " "
echo "You have a directory ~/opencv/build on your disk."
echo "Continuing the installation will replace this folder."
echo " "
printf "Do you wish to continue (Y/n)?"
read answer
if [ "$answer" != "${answer#[Nn]}" ] ;then
echo "Leaving without installing OpenCV"
else
install_opencv
fi
else
install_opencv
fi

26
README copy.md Normal file
View File

@ -0,0 +1,26 @@
https://forums.developer.nvidia.com/t/which-tracker-to-use-to-do-ai-detection-1st-frame-tracking-other-frames/178305/6
1. sudo apt-get install python3-dev
2. install dlib for cuda
wget http://dlib.net/files/dlib-19.22.tar.bz2
tar jxvf dlib-19.22.tar.bz2
cd dlib-19.22/
mkdir build
cd build/
cmake ..
cmake --build .
cd ../
sudo python3 setup.py install
3.
python3
import dlib
dlib.cuda.get_num_devices()
For opencv with virtualenv:
cp -r /usr/local/lib/python3.6/dist-packages/cv2 .
cp -r /usr/lib/python3/dist-packages/numpy .

100
acquire-camera.py Normal file
View File

@ -0,0 +1,100 @@
import cv2
import dlib
import time # To measure time for FPS calculation
# GStreamer pipeline to acquire video from the CSI camera (Jetson Nano)
def gstreamer_pipeline(
sensor_id=0,
capture_width=1280,
capture_height=720,
display_width=640,
display_height=360,
framerate=15,
flip_method=0,
):
return (
f"nvarguscamerasrc sensor-id={sensor_id} ! "
f"video/x-raw(memory:NVMM), width=(int){capture_width}, height=(int){capture_height}, "
f"format=(string)NV12, framerate=(fraction){framerate}/1 ! "
f"nvvidconv flip-method={flip_method} ! "
f"video/x-raw, width=(int){display_width}, height=(int){display_height}, format=(string)BGRx ! "
f"videoconvert ! video/x-raw, format=(string)BGR ! appsink"
)
# Capture from the camera using OpenCV and start tracking
cap = cv2.VideoCapture(gstreamer_pipeline(), cv2.CAP_GSTREAMER)
if not cap.isOpened():
print("Unable to open camera")
else:
# Read the first frame to allow user to draw a bounding box
ret, frame = cap.read()
if not ret:
print("Failed to grab the initial frame")
cap.release()
# Let the user draw the initial bounding box
bbox = cv2.selectROI("Select ROI", frame, fromCenter=False, showCrosshair=True)
# Initialize Dlib correlation tracker
tracker = dlib.correlation_tracker()
tracker.start_track(frame, dlib.rectangle(bbox[0], bbox[1], bbox[0] + bbox[2], bbox[1] + bbox[3]))
img_counter = 0 # To count frames and name images
frame_counter = 0 # To track the number of frames
start_time = time.time() # Start time for FPS calculation
try:
while True:
ret, frame = cap.read()
if not ret:
print("Failed to grab frame")
break
# Start measuring time per frame
frame_start_time = time.time()
# Update the tracker with the current frame
tracker.update(frame)
pos = tracker.get_position()
# Extract the bounding box from the tracker
x1, y1, x2, y2 = int(pos.left()), int(pos.top()), int(pos.right()), int(pos.bottom())
# Draw the updated tracking bounding box on the frame
cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2)
# Show the frame with the tracking rectangle
cv2.imshow("Tracking", frame)
# Save every 10th frame
if frame_counter % 10 == 0:
img_name = f"tracked_frame_{img_counter}.jpg"
cv2.imwrite(img_name, frame)
print(f"Saved {img_name}")
img_counter += 1
# Calculate and print FPS
frame_time = time.time() - frame_start_time
fps = 1.0 / frame_time
print(f"FPS: {fps:.2f}")
frame_counter += 1
# Exit if 'q' is pressed
if cv2.waitKey(1) & 0xFF == ord('q'):
break
except KeyboardInterrupt:
print("Tracking interrupted by user")
cap.release()
cv2.destroyAllWindows()
# Calculate and print average FPS over all frames
end_time = time.time()
total_time = end_time - start_time
average_fps = frame_counter / total_time
print(f"Average FPS: {average_fps:.2f}")
print("Finished tracking")

116
feature_matching.py Normal file
View File

@ -0,0 +1,116 @@
import cv2 as cv
import dlib
import numpy as np
import os
def match_feature_find_object(query_img, train_img, min_matches, results_file_name):
# Create an ORB object
orb = cv.ORB_create(nfeatures=100000)
features1, des1 = orb.detectAndCompute(query_img, None)
features2, des2 = orb.detectAndCompute(train_img, None)
# Create Brute-Force matcher object
bf = cv.BFMatcher(cv.NORM_HAMMING)
matches = bf.knnMatch(des1, des2, k=2)
# Nearest neighbour ratio test to find good matches
good = []
good_without_lists = []
matches = [match for match in matches if len(match) == 2]
for m, n in matches:
if m.distance < 0.8 * n.distance:
good.append([m])
good_without_lists.append(m)
if len(good) >= min_matches:
print(f"good: {len(good)}, {results_file_name}")
# Draw a polygon around the recognized object
src_pts = np.float32([features1[m.queryIdx].pt for m in good_without_lists]).reshape(-1, 1, 2)
dst_pts = np.float32([features2[m.trainIdx].pt for m in good_without_lists]).reshape(-1, 1, 2)
# Get the transformation matrix
M, _ = cv.findHomography(src_pts, dst_pts, cv.RANSAC, 5.0)
# Find the perspective transformation to get the corresponding points
h, w = query_img.shape[:2]
pts = np.float32([[0, 0], [0, h - 1], [w - 1, h - 1], [w - 1, 0]]).reshape(-1, 1, 2)
dst = cv.perspectiveTransform(pts, M)
train_img = cv.polylines(train_img, [np.int32(dst)], True, (0, 255, 0), 2, cv.LINE_AA)
# Return the bounding box of the detected object
x, y, w, h = cv.boundingRect(np.int32(dst))
return (x, y, w, h), train_img # Return bounding box and modified image
else:
print("Not enough good matches are found - {}/{}".format(len(good), min_matches))
return None, train_img # No detection, return None
def main():
input_folder = "extracted_frames/"
output_folder = "results_extracted_frames/"
new_object_size = (300, 300)
os.makedirs(input_folder, exist_ok=True)
os.makedirs(output_folder, exist_ok=True)
orb = cv.ORB_create()
query_img = cv.imread("img/drone.png")
query_img = cv.resize(query_img, new_object_size)
features = orb.detect(query_img, None)
f_img = cv.drawKeypoints(query_img, features, None, color=(0, 255, 0), flags=0)
# cv.imwrite(os.path.join(output_folder, "drone.png"), f_img) # Save the image with keypoints
# Initialize dlib correlation tracker
tracker = dlib.correlation_tracker()
is_tracking = False # Flag to indicate if we are tracking
# Sort the filenames to process them in sequence
filenames = sorted([f for f in os.listdir(input_folder) if f.endswith("png")])
# Previous bounding box (if the object is detected)
prev_bbox = None
for filename in filenames:
img = cv.imread(os.path.join(input_folder, filename))
if not is_tracking: # Try to detect using feature matching
bbox, modified_img = match_feature_find_object(query_img, img, 100, os.path.join(output_folder, filename))
if bbox is not None:
# Object detected, initialize the dlib tracker
x, y, w, h = bbox
tracker.start_track(img, dlib.rectangle(x, y, x + w, y + h))
is_tracking = True
prev_bbox = bbox
else:
# No detection, use the image as is
modified_img = img
else: # If we are tracking
# Update the tracker and get the new position
tracker.update(img)
pos = tracker.get_position()
x1, y1, x2, y2 = int(pos.left()), int(pos.top()), int(pos.right()), int(pos.bottom())
print(x1, y1, x2, y2)
# Draw the tracking bounding box
cv.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2)
# If the bounding box is valid, keep tracking
if (x2 - x1) > 0 and (y2 - y1) > 0:
prev_bbox = (x1, y1, x2 - x1, y2 - y1)
modified_img = img
else:
# If tracking fails, stop tracking and try detection again in the next frame
is_tracking = False
modified_img = img
# Save the result as a PNG image
# cv.imwrite(os.path.join(output_folder, filename), modified_img)
if __name__ == "__main__":
main()

95
generate_images.py Normal file
View File

@ -0,0 +1,95 @@
from PIL import Image, ImageOps
import random
import os
import numpy as np
RANDOM_SEED = 42
random.seed(RANDOM_SEED)
def resize_image(image, target_size):
original_width, original_height = image.size
target_width, target_height = target_size
# Calculate the aspect ratios
width_ratio = target_width / original_width
height_ratio = target_height / original_height
# Use the smaller ratio to ensure the image fits within the target dimensions
scaling_factor = min(width_ratio, height_ratio)
# Calculate new dimensions
new_width = int(original_width * scaling_factor)
new_height = int(original_height * scaling_factor)
# Resize the image
return image.resize((new_width, new_height), Image.LANCZOS)
def rotate_image(image, angle):
return image.rotate(angle, expand=True, resample=Image.Resampling.BICUBIC)
def tilt_image(image, max_tilt_angle=10):
width, height = image.size
# Simulate tilting by applying an affine transformation
tilt_angle = random.uniform(-max_tilt_angle, max_tilt_angle)
x_shift = width * np.sin(np.radians(tilt_angle))
# Affine transformation matrix
if tilt_angle > 0:
transform_matrix = (1, x_shift / height, -x_shift / 2, 0, 1, 0)
else:
transform_matrix = (1, x_shift / height, x_shift / 2, 0, 1, 0)
return image.transform(image.size, Image.AFFINE, transform_matrix, resample=Image.Resampling.BICUBIC)
def generate_images(object_image, output_folder, background_image_path,
background_width=960, background_height=720, num_images=50,
max_rotation_angle=45, max_tilt_angle=10):
background_image = Image.open(background_image_path).convert("RGB")
background_image = background_image.resize((background_width, background_height))
for i in range(num_images):
# Create a copy of the background image
background = background_image.copy()
# Randomly rotate the object image
rotation_angle = random.uniform(-max_rotation_angle, max_rotation_angle)
rotated_image = rotate_image(object_image, rotation_angle)
# Apply random tilt to the object image
tilted_image = tilt_image(rotated_image, max_tilt_angle)
# Random position for the object
max_x = background_width - tilted_image.width
max_y = background_height - tilted_image.height
x = random.randint(0, max_x)
y = random.randint(0, max_y)
# Paste the object image onto the background
background.paste(tilted_image, (x, y), tilted_image)
# Save the new image
background.save(f"{output_folder}/variation_{i + 1}.png")
def main():
background_width = 960
background_height = 720
new_object_size = (300, 300)
os.makedirs("gen_data", exist_ok=True)
output_folder = "gen_data/"
# Load the object image (with transparency)
object_image = Image.open("img/drone.png").convert("RGBA")
object_image = resize_image(object_image, new_object_size)
# Load the background image from a second source
background_image_path = "img/background.jpg"
# Generate images with object placed on top of the background
generate_images(object_image, output_folder, background_image_path,
background_width, background_height, num_images=50)
if __name__ == "__main__":
main()

4
requirements.txt Normal file
View File

@ -0,0 +1,4 @@
pillow==10.4.0
opencv-python==4.10.0.84
numpy==2.1.1
matplotlib==3.9.2