Skip to content

Commit 78d1b55

Browse files
author
salim laimeche
committed
Refactor form labels and input styles
usemodel hooks for re use
1 parent eddd8be commit 78d1b55

File tree

5 files changed

+115
-115
lines changed

5 files changed

+115
-115
lines changed

components/Login.tsx

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -83,18 +83,15 @@ export default function Login() {
8383
name="email"
8484
render={({ field }) => (
8585
<FormItem>
86-
<FormLabel
87-
className={theme === "light" ? "text-black" : "text-white"}>
86+
<FormLabel className="text-indigo-500">
8887
<BlurIn text="Email" balise="span" className="text-sm" />
8988
</FormLabel>
9089
<FormControl>
9190
<Input
9291
type="email"
9392
autoComplete="username"
9493
placeholder="Votre email..."
95-
className={
96-
theme === "light" ? "text-black" : "text-white"
97-
}
94+
className="text-indigo-500"
9895
{...field}
9996
/>
10097
</FormControl>
@@ -107,8 +104,7 @@ export default function Login() {
107104
name="password"
108105
render={({ field }) => (
109106
<FormItem>
110-
<FormLabel
111-
className={theme === "light" ? "text-black" : "text-white"}>
107+
<FormLabel className="text-indigo-500">
112108
<BlurIn
113109
text="Mot de passe"
114110
balise="span"
@@ -120,9 +116,7 @@ export default function Login() {
120116
type="password"
121117
autoComplete="new-password"
122118
placeholder="Votre mot de passe..."
123-
className={
124-
theme === "light" ? "text-black" : "text-white"
125-
}
119+
className="text-indigo-500"
126120
{...field}
127121
/>
128122
</FormControl>
@@ -142,10 +136,7 @@ export default function Login() {
142136
</Button>
143137
</form>
144138
</Form>
145-
<div
146-
className={`mt-4 text-center text-sm z-10 ${
147-
theme === "light" ? "text-black" : "text-white"
148-
}`}>
139+
<div className={`mt-4 text-center text-sm z-10 text-indigo-500`}>
149140
<BlurIn text="Vous n'avez pas de compte ?" balise="span" />
150141
<Link href="/register" className="underline ml-1 border ">
151142
<BlurIn text="Inscrivez-vous" balise="span" className="text-sm" />

components/VideoInference.tsx

Lines changed: 7 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
11
"use client"
22

3-
import "@tensorflow/tfjs-backend-webgl"
4-
import * as tf from "@tensorflow/tfjs"
5-
import { ObjectDetection, load } from "@tensorflow-models/coco-ssd"
63
import { UserView } from "@/lib/identity/definition"
7-
import { useEffect, useState } from "react"
4+
import { useState } from "react"
85
import { ModelComputerVision, ModelList, modelList } from "@/models/model-list"
9-
import { cocossdVideoInference } from "@/lib/cocossd/detect"
106
import { detectVideo } from "@/lib/yolov8n/detect"
117
import ModelLoader from "./model-loader"
128
import { segmentVideo } from "@/lib/yolov8n-seg/detect"
@@ -16,104 +12,19 @@ import VideoReader from "./video-reader"
1612
import VideoSelect from "./video-select"
1713
import { useVideoStore } from "@/hooks/use-video-store"
1814
import { useTfjsBackendWeb } from "@/hooks/use-tfjs-backend"
15+
import useModel from "@/hooks/use-model"
1916

2017
interface IProps {
2118
user: UserView
2219
}
2320

2421
export default function VideoInference({ user }: IProps) {
25-
const [coco, setCoco] = useState<ObjectDetection | null>(null) // init model of COCO SSD
26-
const [yolo, setYolo] = useState({
27-
net: null,
28-
inputShape: [1, 0, 0, 3],
29-
}) // init model & input shape of YOLO DETECTION
30-
const [yoloSeg, setYoloSeg] = useState({
31-
net: null,
32-
inputShape: [1, 0, 0, 3],
33-
}) // init model & input shape of YOLO SEGMENTATION
22+
const ready = useTfjsBackendWeb({ backend: "webgl" })
3423
const [loadModel, setLoadModel] = useState<boolean>(false)
3524
const [percentLoaded, setPercentLoaded] = useState<number>(0)
3625
const { modelName } = useModelStore()
26+
const { model } = useModel({ ready, setLoadModel, setPercentLoaded })
3727
const { canvasRef, videoRef, videoSrc, setVideoSrc } = useVideoStore()
38-
const ready = useTfjsBackendWeb({ backend: "webgl" })
39-
40-
useEffect(() => {
41-
if (!ready) return
42-
console.log("model", modelName)
43-
if (modelName === ModelComputerVision.COCO_SSD) {
44-
yolo?.net?.dispose()
45-
setLoadModel(true)
46-
load()
47-
.then(loadedModel => setCoco(loadedModel))
48-
.catch(err => console.error(err))
49-
.finally(() => setLoadModel(false))
50-
}
51-
52-
if (modelName === ModelComputerVision.DETECTION) {
53-
coco?.dispose()
54-
setLoadModel(true)
55-
setCoco(null)
56-
tf.ready().then(async () => {
57-
const yolov8 = await tf.loadGraphModel(
58-
modelList.find(model => model.title === ModelComputerVision.DETECTION)
59-
?.url as string,
60-
{
61-
onProgress: fractions => {
62-
setPercentLoaded(fractions * 100)
63-
},
64-
}
65-
) // load model
66-
67-
// warming up model
68-
const dummyInput = tf.ones(yolov8.inputs[0].shape)
69-
const warmupResults = yolov8.execute(dummyInput)
70-
71-
setYolo({
72-
net: yolov8,
73-
inputShape: yolov8.inputs[0].shape,
74-
}) // set model & input shape
75-
76-
tf.dispose([warmupResults, dummyInput]) // cleanup memory
77-
setLoadModel(false)
78-
})
79-
}
80-
if (modelName === ModelComputerVision.SEGMENTATION) {
81-
coco?.dispose()
82-
yolo?.net?.dispose()
83-
setLoadModel(true)
84-
tf.ready().then(async () => {
85-
const yolov8 = await tf.loadGraphModel(
86-
modelList.find(
87-
model => model.title === ModelComputerVision.SEGMENTATION
88-
)?.url as string,
89-
{
90-
onProgress: fractions => {
91-
setPercentLoaded(fractions * 100)
92-
},
93-
}
94-
) // load model
95-
96-
// warming up model
97-
const dummyInput = tf.randomUniform(
98-
yolov8.inputs[0].shape,
99-
0,
100-
1,
101-
"float32"
102-
) // random input
103-
const warmupResults = yolov8.execute(dummyInput)
104-
105-
setYoloSeg(prevState => ({
106-
...prevState,
107-
net: yolov8,
108-
inputShape: yolov8.inputs[0].shape,
109-
outputShape: (warmupResults as any).map(e => e.shape),
110-
})) // set model & input shape
111-
112-
tf.dispose([warmupResults, dummyInput]) // cleanup memory
113-
setLoadModel(false)
114-
})
115-
}
116-
}, [modelName, ready])
11728

11829
const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
11930
const file = e.target.files?.[0]
@@ -124,12 +35,10 @@ export default function VideoInference({ user }: IProps) {
12435
}
12536

12637
const handleCreateVideoWithBoundingBox = () => {
127-
if (modelName === ModelComputerVision.COCO_SSD) {
128-
cocossdVideoInference(coco, videoRef, canvasRef)
129-
} else if (modelName === ModelComputerVision.DETECTION) {
130-
detectVideo(videoRef.current, yolo, canvasRef)
38+
if (modelName === ModelComputerVision.DETECTION) {
39+
detectVideo(videoRef.current, model, canvasRef)
13140
} else if (modelName === ModelComputerVision.SEGMENTATION) {
132-
segmentVideo(videoRef.current, yoloSeg as any, canvasRef.current)
41+
segmentVideo(videoRef.current, model as any, canvasRef.current)
13342
}
13443
}
13544

hooks/use-model.tsx

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
import { useModelStore } from "@/lib/store/model-store"
2+
import { useEffect, useState } from "react"
3+
import * as tf from "@tensorflow/tfjs"
4+
import { ModelComputerVision, modelList } from "@/models/model-list"
5+
6+
interface IProps {
7+
ready: boolean
8+
setLoadModel: (value: boolean) => void
9+
setPercentLoaded: (value: number) => void
10+
}
11+
12+
export type ModelGraph = {
13+
net: tf.GraphModel<string | tf.io.IOHandler>
14+
inputShape: number[]
15+
outputShape?: number[]
16+
}
17+
18+
export default function useModel({
19+
ready,
20+
setLoadModel,
21+
setPercentLoaded,
22+
}: IProps) {
23+
const { modelName } = useModelStore()
24+
const [model, setModel] = useState<ModelGraph>(null)
25+
26+
useEffect(() => {
27+
if (!ready) return
28+
console.log("model", modelName)
29+
if (modelName === ModelComputerVision.DETECTION) {
30+
model && model?.net.dispose()
31+
setLoadModel(true)
32+
tf.ready().then(async () => {
33+
const yolov8 = await tf.loadGraphModel(
34+
modelList.find(model => model.title === ModelComputerVision.DETECTION)
35+
?.url as string,
36+
{
37+
onProgress: fractions => {
38+
setPercentLoaded(fractions * 100)
39+
},
40+
}
41+
) // load model
42+
43+
// warming up model
44+
const dummyInput = tf.ones(yolov8.inputs[0].shape)
45+
const warmupResults = yolov8.execute(dummyInput)
46+
47+
setModel({
48+
net: yolov8,
49+
inputShape: yolov8.inputs[0].shape,
50+
}) // set model & input shape
51+
52+
tf.dispose([warmupResults, dummyInput]) // cleanup memory
53+
setLoadModel(false)
54+
})
55+
}
56+
if (modelName === ModelComputerVision.SEGMENTATION) {
57+
model && model?.net.dispose()
58+
setLoadModel(true)
59+
tf.ready().then(async () => {
60+
const yolov8 = await tf.loadGraphModel(
61+
modelList.find(
62+
model => model.title === ModelComputerVision.SEGMENTATION
63+
)?.url as string,
64+
{
65+
onProgress: fractions => {
66+
setPercentLoaded(fractions * 100)
67+
},
68+
}
69+
) // load model
70+
71+
// warming up model
72+
const dummyInput = tf.randomUniform(
73+
yolov8.inputs[0].shape,
74+
0,
75+
1,
76+
"float32"
77+
) // random input
78+
const warmupResults = yolov8.execute(dummyInput)
79+
80+
setModel(prevState => ({
81+
...prevState,
82+
net: yolov8,
83+
inputShape: yolov8.inputs[0].shape,
84+
outputShape: (warmupResults as any).map(
85+
(e: { shape: any }) => e.shape
86+
),
87+
})) // set model & input shape
88+
89+
tf.dispose([warmupResults, dummyInput]) // cleanup memory
90+
setLoadModel(false)
91+
})
92+
}
93+
}, [modelName, ready])
94+
95+
return { model }
96+
}

hooks/use-video-store.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import { useRef, useState } from "react"
1+
import { MutableRefObject, useRef, useState } from "react"
22

33
type VideoStore = {
4-
canvasRef: React.MutableRefObject<HTMLCanvasElement | null>
5-
videoRef: React.MutableRefObject<HTMLVideoElement | null>
4+
canvasRef: MutableRefObject<HTMLCanvasElement | null>
5+
videoRef: MutableRefObject<HTMLVideoElement | null>
66
videoSrc: string | null
77
setVideoSrc: (videoSrc: string | null) => void
88
}

models/model-list.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export type ModelList = {
88
title: ModelComputerVision
99
url: string
1010
description: string
11+
labels?: string
1112
}
1213

1314
export const modelList: ModelList[] = [
@@ -16,17 +17,20 @@ export const modelList: ModelList[] = [
1617
url: "https://tfhub.dev/tensorflow/tfjs-model/ssd_mobilenet_v2/1/default/1",
1718
description:
1819
"Object detection model that aims to localize and identify multiple objects in a single image.",
20+
labels: "basic",
1921
},
2022
{
2123
title: ModelComputerVision.DETECTION,
2224
url: "https://huggingface.co/salim4n/yolov8n_web_model/resolve/main/model.json",
2325
description:
2426
"Object detection model that aims to localize and identify multiple objects in a single image.",
27+
labels: "basic",
2528
},
2629
{
2730
title: ModelComputerVision.SEGMENTATION,
2831
url: "https://huggingface.co/salim4n/yolov8n-segment-web/resolve/main/model.json",
2932
description:
3033
"Semantic segmentation model that assigns a label to each pixel in the image.",
34+
labels: "basic",
3135
},
3236
]

0 commit comments

Comments
 (0)