📦 EyePop.ai — Composable Pops SDK Guide
This guide helps you build, run, and visualize Composable Pops —configurable chains of AI tasks like object detection, OCR, pose estimation, and tracking—using the EyePop SDK.
🧠 What Are Composable Pops?
Composable Pops are dynamic pipelines that link multiple AI components together. Each component can perform inference, forward cropped regions to other models, or trace objects over time. With this system, you can chain object detection → cropping → pose estimation → tracking… and more.
✅ Prerequisites
Make sure you have:
• Node.js >= 18
• Installed packages:
• @eyepop.ai/eyepop
• An EyePop developer account and access to model UUIDs
🔌 Base Imports
Copy import {
ContourType, EndpointState, EyePop,
ForwardOperatorType, InferenceType,
PopComponentType, TransientPopId
} from '@eyepop.ai/eyepop'
🧱 Anatomy of a Pop
A Pop is defined with a list of components, each specifying:
• type: the kind of processing (INFERENCE, TRACING, CONTOUR_FINDER)
• inferenceTypes: what to infer (e.g. OBJECT_DETECTION, OCR)
• modelUuid: model to use
• forward: what to do with the output (e.g. crop, trace, or chain more components)
🧪 Example Pops
1. Text on Detected Objects
Copy const TEXT_ON_OBJECTS = {
components: [{
type: PopComponentType.INFERENCE,
inferenceTypes: [InferenceType.OBJECT_DETECTION],
modelUuid: 'yolov7:...', // your object detector
forward: {
operator: { type: ForwardOperatorType.CROP },
targets: [{
type: PopComponentType.INFERENCE,
inferenceTypes: [InferenceType.OBJECT_DETECTION],
modelUuid: 'eyepop-text:...',
forward: {
operator: { type: ForwardOperatorType.CROP },
targets: [{
type: PopComponentType.INFERENCE,
inferenceTypes: [InferenceType.OCR],
modelUuid: 'PARSeq:...'
}]
}
}]
}
}]
}
Use case: Extract text within labeled objects.
2. Object Tracking
Copy const OBJECT_TRACKING = {
components: [{
type: PopComponentType.INFERENCE,
inferenceTypes: [InferenceType.OBJECT_DETECTION],
modelUuid: 'yolov7:...',
forward: {
operator: { type: ForwardOperatorType.CROP },
targets: [{ type: PopComponentType.TRACING }]
}
}]
}
Use case: Detect and track object movements across frames.
3. Detect Objects and Pose on People
Copy const OBJECT_PLUS_PERSON = {
components: [
{
type: PopComponentType.INFERENCE,
inferenceTypes: [InferenceType.OBJECT_DETECTION],
modelUuid: 'yolov7:...'
},
{
type: PopComponentType.INFERENCE,
inferenceTypes: [InferenceType.OBJECT_DETECTION],
modelUuid: 'eyepop-person:...',
categoryName: 'person',
confidenceThreshold: 0.8,
forward: {
operator: { type: ForwardOperatorType.CROP },
targets: [{
type: PopComponentType.INFERENCE,
inferenceTypes: [InferenceType.KEY_POINTS],
categoryName: '2d-body-points',
modelUuid: 'Mediapipe:...'
}]
}
}
]
}
Use case: Detect all objects and analyze human posture when a person is found.
4. Segmentation and Contour Extraction
Copy const OBJECT_SEGMENTATION = {
components: [{
type: PopComponentType.INFERENCE,
inferenceTypes: [InferenceType.OBJECT_DETECTION],
modelUuid: 'yolov7:...',
forward: {
operator: {
type: ForwardOperatorType.CROP,
crop: { boxPadding: 0.25 }
},
targets: [{
type: PopComponentType.INFERENCE,
inferenceTypes: [InferenceType.SEMANTIC_SEGMENTATION],
modelUuid: 'EfficientSAM:...',
forward: {
operator: { type: ForwardOperatorType.FULL },
targets: [{
type: PopComponentType.CONTOUR_FINDER,
contourType: ContourType.POLYGON
}]
}
}]
}
}]
}
Use case: Get polygon contours of detected objects for precise shape/area analysis.
🧪 Running the Pop
Copy const endpoint = await EyePop.workerEndpoint({
popId: TransientPopId.Transient,
logger
}).connect()
await endpoint.changePop(OBJECT_SEGMENTATION)
const results = await endpoint.process({ path: 'image.jpg' })
for await (const result of results) {
Render2d.renderer(ctx, [Render2d.renderPose(), Render2d.renderText(), Render2d.renderContour()])
.draw(result)
}
🧠 Tips for Building Your Own Pops
• Chain components by specifying forward.targets
• Use ForwardOperatorType.CROP to pass cropped regions
• Use categoryName and confidenceThreshold to filter by label
• Use TRACING or CONTOUR_FINDER for post-processing
🔄 Reusability
Wrap Pops in a function and dynamically switch:
Copy function makeTrackingPop(modelUuid: string) {
return {
components: [{
type: PopComponentType.INFERENCE,
inferenceTypes: [InferenceType.OBJECT_DETECTION],
modelUuid,
forward: {
operator: { type: ForwardOperatorType.CROP },
targets: [{ type: PopComponentType.TRACING }]
}
}]
}
}
🛠️ Troubleshooting
• ✅ Ensure model UUIDs are accessible to your API key
• ⚠️ Use logger.info() to debug endpoint state changes
• 🧪 Try rendering intermediate results to validate your pipeline