gemini model integration
This commit is contained in:
@@ -31,6 +31,7 @@ const DETECTION_METHODS = [
|
|||||||
// { value: 'yoloe_trained_vl', label: 'YOLOE With Vision Language Model' },
|
// { value: 'yoloe_trained_vl', label: 'YOLOE With Vision Language Model' },
|
||||||
{ value: 'culvert_detection', label: 'Culvert Detection' },
|
{ value: 'culvert_detection', label: 'Culvert Detection' },
|
||||||
{ value: 'combined', label: 'Road Defect Detection' },
|
{ value: 'combined', label: 'Road Defect Detection' },
|
||||||
|
{ value: 'gemini_video', label: 'Gemini AI Analysis' },
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
export default function UploadPage() {
|
export default function UploadPage() {
|
||||||
|
|||||||
@@ -86,13 +86,70 @@ export default function VideoPlayerSection({
|
|||||||
// Logs Reducer
|
// Logs Reducer
|
||||||
const [logs, dispatchLogs] = useReducer(logsReducer, []);
|
const [logs, dispatchLogs] = useReducer(logsReducer, []);
|
||||||
|
|
||||||
|
// Memoize a unified data object with frames generated if missing
|
||||||
|
const normalizedData = useMemo(() => {
|
||||||
|
if (data.frames && Array.isArray(data.frames) && data.frames.length > 0) {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Synthesize frames from lists if not present (like in gemini_video)
|
||||||
|
const framesMap = new Map<number, any>();
|
||||||
|
|
||||||
|
// Sort all detections by their first_detected_frame
|
||||||
|
const allDetections: any[] = [];
|
||||||
|
enabledTypes.forEach(type => {
|
||||||
|
const list = (data as any)[type.listKey];
|
||||||
|
if (list && Array.isArray(list)) {
|
||||||
|
list.forEach((item: any) => {
|
||||||
|
allDetections.push({ ...item, _detType: type.id });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
allDetections.sort((a, b) => (a.first_detected_frame || 0) - (b.first_detected_frame || 0));
|
||||||
|
|
||||||
|
// Current counts for sticky stats
|
||||||
|
const currentCounts: Record<string, number> = {};
|
||||||
|
enabledTypes.forEach(t => { currentCounts[t.frameCountKey] = 0; });
|
||||||
|
|
||||||
|
allDetections.forEach(det => {
|
||||||
|
const frameId = det.first_detected_frame || det.frame_number || 0;
|
||||||
|
|
||||||
|
if (!framesMap.has(frameId)) {
|
||||||
|
framesMap.set(frameId, { frame_id: frameId, detections: [] });
|
||||||
|
}
|
||||||
|
|
||||||
|
const frameData = framesMap.get(frameId);
|
||||||
|
|
||||||
|
// Update cumulative counts
|
||||||
|
const typeConfig = enabledTypes.find(t => t.id === det._detType);
|
||||||
|
if (typeConfig) {
|
||||||
|
currentCounts[typeConfig.frameCountKey] = (currentCounts[typeConfig.frameCountKey] || 0) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const countCopy = { ...currentCounts };
|
||||||
|
|
||||||
|
frameData.detections.push({
|
||||||
|
...det,
|
||||||
|
type: det.type || det._detType,
|
||||||
|
detection_id: det.detection_id || det.id,
|
||||||
|
count: countCopy
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
...data,
|
||||||
|
frames: Array.from(framesMap.values()).sort((a, b) => (a.frame_id || 0) - (b.frame_id || 0))
|
||||||
|
};
|
||||||
|
}, [data, enabledTypes]);
|
||||||
|
|
||||||
// Custom Hooks
|
// Custom Hooks
|
||||||
const gpsMap = useGpsMap(data);
|
const gpsMap = useGpsMap(normalizedData);
|
||||||
const { getNearestDetections, sortedDetectionIndices } = useFrameDetectionMap(
|
const { getNearestDetections, sortedDetectionIndices } = useFrameDetectionMap(
|
||||||
data,
|
normalizedData,
|
||||||
detectionType,
|
detectionType,
|
||||||
);
|
);
|
||||||
const { getStickyCounts, sortedFrameIndices } = useCumulativeCounts(data.frames);
|
const { getStickyCounts, sortedFrameIndices } = useCumulativeCounts(normalizedData.frames || []);
|
||||||
|
|
||||||
// Memoized video URL
|
// Memoized video URL
|
||||||
const videoUrl = useMemo(() => {
|
const videoUrl = useMemo(() => {
|
||||||
|
|||||||
@@ -136,6 +136,20 @@ export const DETECTION_MODES: Record<string, DetectionModeConfig> = {
|
|||||||
label: 'Culvert Detection',
|
label: 'Culvert Detection',
|
||||||
enabledTypes: ['good_culvert', 'defective_culvert'],
|
enabledTypes: ['good_culvert', 'defective_culvert'],
|
||||||
},
|
},
|
||||||
|
gemini_video: {
|
||||||
|
id: 'gemini_video',
|
||||||
|
label: 'Gemini AI Analysis',
|
||||||
|
enabledTypes: [
|
||||||
|
'pothole',
|
||||||
|
'defected_sign_board',
|
||||||
|
'road_crack',
|
||||||
|
'damaged_road_marking',
|
||||||
|
'good_sign_board',
|
||||||
|
'drain_issue',
|
||||||
|
'good_culvert',
|
||||||
|
'defective_culvert',
|
||||||
|
],
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// Fallback config for unknown modes
|
// Fallback config for unknown modes
|
||||||
|
|||||||
@@ -22,7 +22,8 @@ export type DetectionType =
|
|||||||
| 'yolo_vl'
|
| 'yolo_vl'
|
||||||
| 'sam3'
|
| 'sam3'
|
||||||
| 'yoloe'
|
| 'yoloe'
|
||||||
| 'yoloe_trained_vl';
|
| 'yoloe_trained_vl'
|
||||||
|
| 'gemini_video';
|
||||||
|
|
||||||
export interface DetectionListItem {
|
export interface DetectionListItem {
|
||||||
detection_id?: number;
|
detection_id?: number;
|
||||||
|
|||||||
Reference in New Issue
Block a user