From 51bd92d65aa30a9f18b37d5518f2b147054f2b95 Mon Sep 17 00:00:00 2001 From: Victor Mylle Date: Wed, 22 Mar 2023 21:21:44 +0000 Subject: [PATCH] Added train, val, test selctor --- ...6612906_add_dataset_column_to_signvideo.py | 43 +++++++++++++++++++ backend/src/models/signvideo.py | 4 +- backend/src/routers/signvideo.py | 6 +++ frontend/src/components/RandomVideoUpload.tsx | 4 +- frontend/src/components/SignDetailPage.tsx | 21 +++++++-- frontend/src/components/SignVideoPlayer.tsx | 18 +++++++- frontend/src/services/signvideos.ts | 6 +-- frontend/src/types/sign.ts | 1 + 8 files changed, 92 insertions(+), 11 deletions(-) create mode 100755 backend/alembic/versions/3afa46612906_add_dataset_column_to_signvideo.py diff --git a/backend/alembic/versions/3afa46612906_add_dataset_column_to_signvideo.py b/backend/alembic/versions/3afa46612906_add_dataset_column_to_signvideo.py new file mode 100755 index 0000000..c82ca9b --- /dev/null +++ b/backend/alembic/versions/3afa46612906_add_dataset_column_to_signvideo.py @@ -0,0 +1,43 @@ +"""add dataset column to signvideo + +Revision ID: 3afa46612906 +Revises: 2d2d4523082b +Create Date: 2023-03-22 20:54:32.035246 + +""" +import sqlalchemy as sa +import sqlmodel + +from alembic import op + +# revision identifiers, used by Alembic. +revision = '3afa46612906' +down_revision = '2d2d4523082b' +branch_labels = None +depends_on = None + + +def upgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table('sign', schema=None) as batch_op: + batch_op.alter_column('category_id', + existing_type=sa.INTEGER(), + nullable=False) + + with op.batch_alter_table('signvideo', schema=None) as batch_op: + batch_op.add_column(sa.Column('dataset', sqlmodel.sql.sqltypes.AutoString(), nullable=False, server_default='train')) + + # ### end Alembic commands ### + + +def downgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table('signvideo', schema=None) as batch_op: + batch_op.drop_column('dataset') + + with op.batch_alter_table('sign', schema=None) as batch_op: + batch_op.alter_column('category_id', + existing_type=sa.INTEGER(), + nullable=True) + + # ### end Alembic commands ### diff --git a/backend/src/models/signvideo.py b/backend/src/models/signvideo.py index a7ba105..493139a 100644 --- a/backend/src/models/signvideo.py +++ b/backend/src/models/signvideo.py @@ -9,6 +9,7 @@ class SignVideo(SQLModelExtended, table=True): id: int = Field(primary_key=True) approved: bool = False + dataset: str = "train" # train, test, val # foreign key to sign sign_id: int = Field(default=None, foreign_key="sign.id") @@ -22,4 +23,5 @@ class SignVideo(SQLModelExtended, table=True): class SignVideoOut(BaseModel): id: int - approved: bool \ No newline at end of file + approved: bool + dataset: str \ No newline at end of file diff --git a/backend/src/routers/signvideo.py b/backend/src/routers/signvideo.py index b975084..b42e6f7 100644 --- a/backend/src/routers/signvideo.py +++ b/backend/src/routers/signvideo.py @@ -157,6 +157,7 @@ async def sign_video( class SignVideoUpdate(BaseModel): approved: bool + dataset: str @router.patch("/{video_id}/", status_code=status.HTTP_200_OK) async def sign_video( @@ -178,7 +179,12 @@ async def sign_video( if not sign_video: raise BaseException("Sign video not found") + # check if dataset is train, val or test + if update.dataset not in ["train", "val", "test"]: + raise BaseException("Dataset must be train, val or test") + sign_video.approved = update.approved + sign_video.dataset = update.dataset await sign_video.save(session) diff --git a/frontend/src/components/RandomVideoUpload.tsx b/frontend/src/components/RandomVideoUpload.tsx index a7c00ad..a72f63e 100755 --- a/frontend/src/components/RandomVideoUpload.tsx +++ b/frontend/src/components/RandomVideoUpload.tsx @@ -3,11 +3,9 @@ import { Sign, SignVideo, SimpleSign } from '../types/sign'; import { useParams } from 'react-router-dom'; import { getRandomSign, getSign } from '../services/signs'; import ReactModal from 'react-modal'; -import { acceptVideo, deleteVideo, uploadSignVideo } from '../services/signvideos'; +import { uploadSignVideo } from '../services/signvideos'; import { LoadingButton } from './loading-button/loading-button'; import VideoRecorder from 'react-video-recorder'; -import SignVideoGrid from './SignVideoGrid'; -import SignVideoPlayer from './SignVideoPlayer'; const RandomSignUpload: React.FC = () => { diff --git a/frontend/src/components/SignDetailPage.tsx b/frontend/src/components/SignDetailPage.tsx index b06e1f1..7189a51 100644 --- a/frontend/src/components/SignDetailPage.tsx +++ b/frontend/src/components/SignDetailPage.tsx @@ -3,7 +3,7 @@ import { Sign, SignVideo } from '../types/sign'; import { useParams } from 'react-router-dom'; import { getSign } from '../services/signs'; import ReactModal from 'react-modal'; -import { acceptVideo, deleteVideo, uploadSignVideo } from '../services/signvideos'; +import { updateVideo, deleteVideo, uploadSignVideo } from '../services/signvideos'; import { LoadingButton } from './loading-button/loading-button'; import VideoRecorder from 'react-video-recorder'; import SignVideoGrid from './SignVideoGrid'; @@ -52,7 +52,7 @@ const SignDetailpage: React.FC = (props) => { if (sign != null && currentVideo != null) { console.log('accepting video'); - acceptVideo(sign.id, sign.sign_videos[currentVideo].id, approved).then((response) => { + updateVideo(sign.id, sign.sign_videos[currentVideo].id, approved, sign.sign_videos[currentVideo].dataset).then((response) => { const newSign = { ...sign }; const newSignVideo = { ...newSign.sign_videos[currentVideo] }; newSignVideo.approved = approved; @@ -62,6 +62,21 @@ const SignDetailpage: React.FC = (props) => { } } + const updateDatasetSignVideo = (dataset: string) => { + // update the sign video in the sign + if (sign != null && currentVideo != null) { + console.log('updating dataset'); + + updateVideo(sign.id, sign.sign_videos[currentVideo].id, sign.sign_videos[currentVideo].approved, dataset).then((response) => { + const newSign = { ...sign }; + const newSignVideo = { ...newSign.sign_videos[currentVideo] }; + newSignVideo.dataset = dataset; + newSign.sign_videos[currentVideo] = newSignVideo; + setSign(newSign); + }); + } + } + const deleteSignVideo = () => { deleteVideo(sign!.id, sign!.sign_videos[currentVideo!].id).then((response) => { const newSign = { ...sign! }; @@ -140,7 +155,7 @@ const SignDetailpage: React.FC = (props) => { timeLimit={4000} /> : - + } diff --git a/frontend/src/components/SignVideoPlayer.tsx b/frontend/src/components/SignVideoPlayer.tsx index 151bd26..f08d4ce 100644 --- a/frontend/src/components/SignVideoPlayer.tsx +++ b/frontend/src/components/SignVideoPlayer.tsx @@ -12,10 +12,11 @@ interface Props { sign_id: number; sign_video: SignVideo; approveSignVideo: (approve: boolean) => void; + datasetSignVideo: (dataset: string) => void; deleteSignVideo: () => void; } -const SignVideoPlayer: React.FC = ({ sign_id, sign_video, approveSignVideo, deleteSignVideo }) => { +const SignVideoPlayer: React.FC = ({ sign_id, sign_video, approveSignVideo, deleteSignVideo, datasetSignVideo }) => { const [videoBlob, setVideoBlob] = useState(null) const [showConfirm, setShowConfirm] = useState(false); @@ -38,6 +39,10 @@ const SignVideoPlayer: React.FC = ({ sign_id, sign_video, approveSignVide deleteSignVideo(); } + const handleTypeChange = (e: React.ChangeEvent) => { + datasetSignVideo(e.target.value); + } + useEffect(() => { getVideo(sign_id, sign_video.id).then((response) => { setVideoBlob(URL.createObjectURL(response)) @@ -59,6 +64,17 @@ const SignVideoPlayer: React.FC = ({ sign_id, sign_video, approveSignVide > {!sign_video.approved ? "Accept video" : "Reject video"} + + +