Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,9 @@ thirdparty/gst-build/gst-build-1.16
base/vcpkg_installed
base/vcpkg.json
CI_test_result*.xml

# Sample executables and build artifacts
samples/**/build/
samples/**/*.exe
samples/**/*.out
samples/**/data/output/
95 changes: 95 additions & 0 deletions HOW_TO_RUN_FACE_DETECTION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# How to Run Face Detection CPU Sample

## Location
The executable is located at:
```
D:\dws\ApraPipes\samples\_build\RelWithDebInfo\face_detection_cpu.exe
```

## Prerequisites
- Webcam connected to your computer
- Caffe model files (already in place at `./data/assets/`)

## Running the Sample

### Option 1: From PowerShell/Command Prompt
```powershell
cd D:\dws\ApraPipes\samples\_build\RelWithDebInfo
.\face_detection_cpu.exe
```

### Option 2: From Project Root
```powershell
cd D:\dws\ApraPipes\samples\_build\RelWithDebInfo
.\face_detection_cpu.exe
```

### Option 3: Double-click
You can also double-click the executable in Windows Explorer:
```
D:\dws\ApraPipes\samples\_build\RelWithDebInfo\face_detection_cpu.exe
```

## What to Expect

When you run the sample:
1. Console output will show pipeline setup information
2. A window will open showing your webcam feed
3. **Green rectangles** will appear around detected faces
4. **White text** will show the confidence score (as a percentage) above each face
5. Press `ESC` or `Q` to quit

## Sample Output
```
============================================================
ApraPipes Sample: Face Detection CPU
=============================================================

Setting up face detection pipeline...
Camera ID: 0
Scale Factor: 1
Detection Threshold: 0.7
Model paths (hardcoded in FaceDetectorXform):
Config: ./data/assets/deploy.prototxt
Weights: ./data/assets/res10_300x300_ssd_iter_140000_fp16.caffemodel

2025-Oct-13 XX:XX:XX [info] Registering built-in metadata conversions...
2025-Oct-13 XX:XX:XX [info] <OverlayModule_3>::validateInputPins Auto-conversion available from 17 to 11
✓ Pipeline setup completed successfully!
✓ Pipeline initialized successfully!

Pipeline running! Press ESC or Q in the viewer window to stop...
```

## Features Demonstrated

This sample demonstrates the **automatic metadata type conversion** feature:

1. **FaceDetectorXform** outputs `FACEDETECTS_INFO` (type 17) metadata
2. **OverlayModule** expects `OVERLAY_INFO_IMAGE` (type 11) metadata
3. **MetadataRegistry** automatically converts between these types
4. The conversion creates visualization with:
- Green bounding boxes around faces
- White text showing confidence percentages

No manual converter module is needed - the conversion happens automatically!

## Troubleshooting

### Camera Not Found
If you see "Failed to open camera", check:
- Webcam is connected
- No other application is using the webcam
- Camera permissions are granted

### Model Files Missing
If you see model file errors:
```bash
# Copy model files to the correct location
cd D:\dws\ApraPipes
cp -r data samples\_build\RelWithDebInfo\
```

### No Window Appears
- Make sure you're running from the correct directory
- Check that all DLLs were copied (should happen automatically during build)
18 changes: 16 additions & 2 deletions base/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ ENDIF(ENABLE_LINUX)
IF(ENABLE_WINDOWS)
add_compile_definitions(WINDOWS)
set(VCPKG_TARGET_TRIPLET "x64-windows" CACHE STRING "x64-windows")
set(VCPKG_PLATFORM_TOOLSET "v143" CACHE STRING "v143" FORCE)
set(VCPKG_PLATFORM_TOOLSET "v142" CACHE STRING "v142" FORCE)
ENDIF(ENABLE_WINDOWS)

IF(ENABLE_ARM64)
Expand All @@ -34,13 +34,22 @@ add_compile_options($<$<COMPILE_LANG_AND_ID:CXX,MSVC>:/MP>)

set(CMAKE_CXX_STANDARD 17)

IF(ENABLE_CUDA)
enable_language(CUDA)
set(CMAKE_CUDA_STANDARD 17)
ENDIF()

project(APRAPIPES)

message(STATUS $ENV{PKG_CONFIG_PATH}">>>>>> PKG_CONFIG_PATH")

find_package(PkgConfig REQUIRED)
find_package(Boost COMPONENTS system thread filesystem serialization log chrono unit_test_framework REQUIRED)
find_package(JPEG REQUIRED)

# Add custom cmake modules directory for FindCUDA.cmake compatibility
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")

find_package(OpenCV CONFIG REQUIRED)
find_package(BZip2 REQUIRED)
find_package(ZLIB REQUIRED)
Expand Down Expand Up @@ -337,13 +346,17 @@ SET(IP_FILES
src/Overlay.cpp
src/OverlayFactory.h
src/OverlayFactory.cpp
src/ApraFaceInfo.cpp
src/TestSignalGeneratorSrc.cpp
src/AudioToTextXForm.cpp
src/AudioToTextXForm.cpp
src/AbsControlModule.cpp
src/ThumbnailListGenerator.cpp
src/MetadataRegistry.cpp
src/MetadataRegistryInit.cpp
)

SET(IP_FILES_H
include/IMetadataConvertible.h
include/HistogramOverlay.h
include/CalcHistogramCV.h
include/ApraPoint2f.h
Expand All @@ -367,6 +380,7 @@ SET(IP_FILES_H
include/Overlay.h
include/AudioToTextXForm.h
include/ThumbnailListGenerator.h
include/MetadataRegistry.h
)

SET(CUDA_CORE_FILES
Expand Down
96 changes: 96 additions & 0 deletions base/cmake/FindCUDA.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# Compatibility FindCUDA.cmake for modern CMake with CUDA language support
# This bridges legacy find_package(CUDA) calls to modern enable_language(CUDA)

# Legacy function from old FindCUDA.cmake
function(find_cuda_helper_libs LIBRARY_NAME)
find_package(CUDAToolkit REQUIRED)

# Map library names to modern CUDAToolkit targets
if(LIBRARY_NAME STREQUAL "cublas")
set(${LIBRARY_NAME}_LIBRARY CUDA::cublas PARENT_SCOPE)
elseif(LIBRARY_NAME STREQUAL "cufft")
set(${LIBRARY_NAME}_LIBRARY CUDA::cufft PARENT_SCOPE)
elseif(LIBRARY_NAME STREQUAL "curand")
set(${LIBRARY_NAME}_LIBRARY CUDA::curand PARENT_SCOPE)
elseif(LIBRARY_NAME STREQUAL "cusparse")
set(${LIBRARY_NAME}_LIBRARY CUDA::cusparse PARENT_SCOPE)
elseif(LIBRARY_NAME STREQUAL "cusolver")
set(${LIBRARY_NAME}_LIBRARY CUDA::cusolver PARENT_SCOPE)
elseif(LIBRARY_NAME STREQUAL "nppc")
set(${LIBRARY_NAME}_LIBRARY CUDA::nppc PARENT_SCOPE)
elseif(LIBRARY_NAME STREQUAL "nppial")
set(${LIBRARY_NAME}_LIBRARY CUDA::nppial PARENT_SCOPE)
elseif(LIBRARY_NAME STREQUAL "nppicc")
set(${LIBRARY_NAME}_LIBRARY CUDA::nppicc PARENT_SCOPE)
elseif(LIBRARY_NAME STREQUAL "nppidei")
set(${LIBRARY_NAME}_LIBRARY CUDA::nppidei PARENT_SCOPE)
elseif(LIBRARY_NAME STREQUAL "nppif")
set(${LIBRARY_NAME}_LIBRARY CUDA::nppif PARENT_SCOPE)
elseif(LIBRARY_NAME STREQUAL "nppig")
set(${LIBRARY_NAME}_LIBRARY CUDA::nppig PARENT_SCOPE)
elseif(LIBRARY_NAME STREQUAL "nppim")
set(${LIBRARY_NAME}_LIBRARY CUDA::nppim PARENT_SCOPE)
elseif(LIBRARY_NAME STREQUAL "nppist")
set(${LIBRARY_NAME}_LIBRARY CUDA::nppist PARENT_SCOPE)
elseif(LIBRARY_NAME STREQUAL "nppisu")
set(${LIBRARY_NAME}_LIBRARY CUDA::nppisu PARENT_SCOPE)
elseif(LIBRARY_NAME STREQUAL "nppitc")
set(${LIBRARY_NAME}_LIBRARY CUDA::nppitc PARENT_SCOPE)
elseif(LIBRARY_NAME STREQUAL "npps")
set(${LIBRARY_NAME}_LIBRARY CUDA::npps PARENT_SCOPE)
elseif(LIBRARY_NAME STREQUAL "cudart")
set(${LIBRARY_NAME}_LIBRARY CUDA::cudart PARENT_SCOPE)
else()
message(WARNING "Unknown CUDA library: ${LIBRARY_NAME}")
endif()
endfunction()

if(NOT CUDA_FOUND)
# Enable CUDA language if not already enabled
if(NOT CMAKE_CUDA_COMPILER)
enable_language(CUDA)
endif()

# Find CUDAToolkit using modern CMake
find_package(CUDAToolkit ${CUDA_FIND_VERSION} QUIET)

if(CUDAToolkit_FOUND)
set(CUDA_FOUND TRUE)
set(CUDA_VERSION ${CUDAToolkit_VERSION})
set(CUDA_VERSION_MAJOR ${CUDAToolkit_VERSION_MAJOR})
set(CUDA_VERSION_MINOR ${CUDAToolkit_VERSION_MINOR})
set(CUDA_TOOLKIT_ROOT_DIR ${CUDAToolkit_TARGET_DIR})
set(CUDA_INCLUDE_DIRS ${CUDAToolkit_INCLUDE_DIRS})

# Set library paths
set(CUDA_LIBRARIES ${CUDA_CUDART_LIBRARY})
set(CUDA_CUDART_LIBRARY ${CUDA_cudart_LIBRARY})
set(CUDA_cublas_LIBRARY CUDA::cublas)
set(CUDA_cufft_LIBRARY CUDA::cufft)
set(CUDA_curand_LIBRARY CUDA::curand)
set(CUDA_cusparse_LIBRARY CUDA::cusparse)
set(CUDA_cusolver_LIBRARY CUDA::cusolver)
set(CUDA_nppc_LIBRARY CUDA::nppc)
set(CUDA_nppial_LIBRARY CUDA::nppial)
set(CUDA_nppicc_LIBRARY CUDA::nppicc)
set(CUDA_nppidei_LIBRARY CUDA::nppidei)
set(CUDA_nppif_LIBRARY CUDA::nppif)
set(CUDA_nppig_LIBRARY CUDA::nppig)
set(CUDA_nppim_LIBRARY CUDA::nppim)
set(CUDA_nppist_LIBRARY CUDA::nppist)
set(CUDA_nppisu_LIBRARY CUDA::nppisu)
set(CUDA_nppitc_LIBRARY CUDA::nppitc)
set(CUDA_npps_LIBRARY CUDA::npps)

# For compatibility with older FindCUDA usage
set(CUDA_USE_STATIC_CUDA_RUNTIME OFF)
else()
set(CUDA_FOUND FALSE)
endif()
endif()

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(CUDA
REQUIRED_VARS CUDA_INCLUDE_DIRS
VERSION_VAR CUDA_VERSION
)
19 changes: 18 additions & 1 deletion base/include/ApraFaceInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,20 @@
#include <boost/serialization/base_object.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include "IMetadataConvertible.h"
#include <sstream>
#include <iomanip>

class ApraFaceInfo
// Forward declaration to avoid circular dependency
class DrawingOverlay;

/**
* @brief Face detection information structure with metadata conversion support
*
* Represents a detected face with bounding box coordinates and confidence score.
* Implements IMetadataConvertible to enable automatic conversion to overlay visualization.
*/
class ApraFaceInfo : public IMetadataConvertible
{
public:
float x1, x2, y1, y2, score;
Expand All @@ -22,6 +34,11 @@ class ApraFaceInfo
return sizeof(ApraFaceInfo) + sizeof(x1) + sizeof(x2) + sizeof(y1) + sizeof(y2) + sizeof(score) + 32;
}

// IMetadataConvertible interface implementation
std::vector<FrameMetadata::FrameType> getConvertibleTypes() const override;
void* convertTo(FrameMetadata::FrameType targetType, size_t& outSize) const override;
FrameMetadata::FrameType getNativeType() const override;

private:
friend class boost::serialization::access;

Expand Down
64 changes: 64 additions & 0 deletions base/include/IMetadataConvertible.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#pragma once

#include "FrameMetadata.h"
#include <vector>

/**
* @brief Interface for metadata structures that can convert to other metadata types
*
* This interface enables automatic metadata type conversion in the pipeline framework.
* Implementing classes declare which metadata types they can convert to and provide
* conversion logic.
*
* Example usage:
* @code
* class ApraFaceInfo : public IMetadataConvertible {
* std::vector<FrameMetadata::FrameType> getConvertibleTypes() const override {
* return {FrameMetadata::OVERLAY_INFO_IMAGE};
* }
*
* void* convertTo(FrameMetadata::FrameType targetType, size_t& outSize) const override {
* if (targetType == FrameMetadata::OVERLAY_INFO_IMAGE) {
* return createOverlayRepresentation(outSize);
* }
* return nullptr;
* }
* };
* @endcode
*
* This is Phase 1 of the Intelligent Pipeline Framework (see intelligent_pipeline_design.md)
*/
class IMetadataConvertible {
public:
virtual ~IMetadataConvertible() {}

/**
* @brief Get list of metadata types this can convert to
* @return Vector of FrameMetadata::FrameType values
*/
virtual std::vector<FrameMetadata::FrameType> getConvertibleTypes() const = 0;

/**
* @brief Convert to specified metadata type
* @param targetType The desired metadata type
* @param outSize Output parameter for size of returned data
* @return Pointer to converted data (caller owns memory), or nullptr if conversion not supported
*/
virtual void* convertTo(FrameMetadata::FrameType targetType, size_t& outSize) const = 0;

/**
* @brief Get the native metadata type of this data structure
* @return The FrameMetadata::FrameType representing this data's native type
*/
virtual FrameMetadata::FrameType getNativeType() const = 0;

/**
* @brief Check if conversion to a specific type is supported
* @param targetType The type to check
* @return true if conversion is supported, false otherwise
*/
virtual bool canConvertTo(FrameMetadata::FrameType targetType) const {
auto types = getConvertibleTypes();
return std::find(types.begin(), types.end(), targetType) != types.end();
}
};
Loading
Loading