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: 'culvert_detection', label: 'Culvert Detection' },
|
||||
{ value: 'combined', label: 'Road Defect Detection' },
|
||||
{ value: 'gemini_video', label: 'Gemini AI Analysis' },
|
||||
] as const;
|
||||
|
||||
export default function UploadPage() {
|
||||
|
||||
@@ -86,13 +86,70 @@ export default function VideoPlayerSection({
|
||||
// Logs Reducer
|
||||
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
|
||||
const gpsMap = useGpsMap(data);
|
||||
const gpsMap = useGpsMap(normalizedData);
|
||||
const { getNearestDetections, sortedDetectionIndices } = useFrameDetectionMap(
|
||||
data,
|
||||
normalizedData,
|
||||
detectionType,
|
||||
);
|
||||
const { getStickyCounts, sortedFrameIndices } = useCumulativeCounts(data.frames);
|
||||
const { getStickyCounts, sortedFrameIndices } = useCumulativeCounts(normalizedData.frames || []);
|
||||
|
||||
// Memoized video URL
|
||||
const videoUrl = useMemo(() => {
|
||||
|
||||
@@ -136,6 +136,20 @@ export const DETECTION_MODES: Record<string, DetectionModeConfig> = {
|
||||
label: 'Culvert Detection',
|
||||
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
|
||||
|
||||
@@ -22,7 +22,8 @@ export type DetectionType =
|
||||
| 'yolo_vl'
|
||||
| 'sam3'
|
||||
| 'yoloe'
|
||||
| 'yoloe_trained_vl';
|
||||
| 'yoloe_trained_vl'
|
||||
| 'gemini_video';
|
||||
|
||||
export interface DetectionListItem {
|
||||
detection_id?: number;
|
||||
|
||||
Reference in New Issue
Block a user