Added train, val, test selctor
This commit is contained in:
43
backend/alembic/versions/3afa46612906_add_dataset_column_to_signvideo.py
Executable file
43
backend/alembic/versions/3afa46612906_add_dataset_column_to_signvideo.py
Executable file
@@ -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 ###
|
||||||
@@ -9,6 +9,7 @@ class SignVideo(SQLModelExtended, table=True):
|
|||||||
id: int = Field(primary_key=True)
|
id: int = Field(primary_key=True)
|
||||||
|
|
||||||
approved: bool = False
|
approved: bool = False
|
||||||
|
dataset: str = "train" # train, test, val
|
||||||
|
|
||||||
# foreign key to sign
|
# foreign key to sign
|
||||||
sign_id: int = Field(default=None, foreign_key="sign.id")
|
sign_id: int = Field(default=None, foreign_key="sign.id")
|
||||||
@@ -22,4 +23,5 @@ class SignVideo(SQLModelExtended, table=True):
|
|||||||
|
|
||||||
class SignVideoOut(BaseModel):
|
class SignVideoOut(BaseModel):
|
||||||
id: int
|
id: int
|
||||||
approved: bool
|
approved: bool
|
||||||
|
dataset: str
|
||||||
@@ -157,6 +157,7 @@ async def sign_video(
|
|||||||
|
|
||||||
class SignVideoUpdate(BaseModel):
|
class SignVideoUpdate(BaseModel):
|
||||||
approved: bool
|
approved: bool
|
||||||
|
dataset: str
|
||||||
|
|
||||||
@router.patch("/{video_id}/", status_code=status.HTTP_200_OK)
|
@router.patch("/{video_id}/", status_code=status.HTTP_200_OK)
|
||||||
async def sign_video(
|
async def sign_video(
|
||||||
@@ -178,7 +179,12 @@ async def sign_video(
|
|||||||
if not sign_video:
|
if not sign_video:
|
||||||
raise BaseException("Sign video not found")
|
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.approved = update.approved
|
||||||
|
sign_video.dataset = update.dataset
|
||||||
await sign_video.save(session)
|
await sign_video.save(session)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -3,11 +3,9 @@ import { Sign, SignVideo, SimpleSign } from '../types/sign';
|
|||||||
import { useParams } from 'react-router-dom';
|
import { useParams } from 'react-router-dom';
|
||||||
import { getRandomSign, getSign } from '../services/signs';
|
import { getRandomSign, getSign } from '../services/signs';
|
||||||
import ReactModal from 'react-modal';
|
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 { LoadingButton } from './loading-button/loading-button';
|
||||||
import VideoRecorder from 'react-video-recorder';
|
import VideoRecorder from 'react-video-recorder';
|
||||||
import SignVideoGrid from './SignVideoGrid';
|
|
||||||
import SignVideoPlayer from './SignVideoPlayer';
|
|
||||||
|
|
||||||
|
|
||||||
const RandomSignUpload: React.FC = () => {
|
const RandomSignUpload: React.FC = () => {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { Sign, SignVideo } from '../types/sign';
|
|||||||
import { useParams } from 'react-router-dom';
|
import { useParams } from 'react-router-dom';
|
||||||
import { getSign } from '../services/signs';
|
import { getSign } from '../services/signs';
|
||||||
import ReactModal from 'react-modal';
|
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 { LoadingButton } from './loading-button/loading-button';
|
||||||
import VideoRecorder from 'react-video-recorder';
|
import VideoRecorder from 'react-video-recorder';
|
||||||
import SignVideoGrid from './SignVideoGrid';
|
import SignVideoGrid from './SignVideoGrid';
|
||||||
@@ -52,7 +52,7 @@ const SignDetailpage: React.FC<Props> = (props) => {
|
|||||||
if (sign != null && currentVideo != null) {
|
if (sign != null && currentVideo != null) {
|
||||||
console.log('accepting video');
|
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 newSign = { ...sign };
|
||||||
const newSignVideo = { ...newSign.sign_videos[currentVideo] };
|
const newSignVideo = { ...newSign.sign_videos[currentVideo] };
|
||||||
newSignVideo.approved = approved;
|
newSignVideo.approved = approved;
|
||||||
@@ -62,6 +62,21 @@ const SignDetailpage: React.FC<Props> = (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 = () => {
|
const deleteSignVideo = () => {
|
||||||
deleteVideo(sign!.id, sign!.sign_videos[currentVideo!].id).then((response) => {
|
deleteVideo(sign!.id, sign!.sign_videos[currentVideo!].id).then((response) => {
|
||||||
const newSign = { ...sign! };
|
const newSign = { ...sign! };
|
||||||
@@ -140,7 +155,7 @@ const SignDetailpage: React.FC<Props> = (props) => {
|
|||||||
|
|
||||||
timeLimit={4000}
|
timeLimit={4000}
|
||||||
/> :
|
/> :
|
||||||
<SignVideoPlayer sign_id={sign.id} sign_video={sign.sign_videos[currentVideo]} approveSignVideo={acceptSignVideo} deleteSignVideo={deleteSignVideo} />
|
<SignVideoPlayer sign_id={sign.id} sign_video={sign.sign_videos[currentVideo]} datasetSignVideo={updateDatasetSignVideo} approveSignVideo={acceptSignVideo} deleteSignVideo={deleteSignVideo} />
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -12,10 +12,11 @@ interface Props {
|
|||||||
sign_id: number;
|
sign_id: number;
|
||||||
sign_video: SignVideo;
|
sign_video: SignVideo;
|
||||||
approveSignVideo: (approve: boolean) => void;
|
approveSignVideo: (approve: boolean) => void;
|
||||||
|
datasetSignVideo: (dataset: string) => void;
|
||||||
deleteSignVideo: () => void;
|
deleteSignVideo: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const SignVideoPlayer: React.FC<Props> = ({ sign_id, sign_video, approveSignVideo, deleteSignVideo }) => {
|
const SignVideoPlayer: React.FC<Props> = ({ sign_id, sign_video, approveSignVideo, deleteSignVideo, datasetSignVideo }) => {
|
||||||
const [videoBlob, setVideoBlob] = useState<string | null>(null)
|
const [videoBlob, setVideoBlob] = useState<string | null>(null)
|
||||||
const [showConfirm, setShowConfirm] = useState(false);
|
const [showConfirm, setShowConfirm] = useState(false);
|
||||||
|
|
||||||
@@ -38,6 +39,10 @@ const SignVideoPlayer: React.FC<Props> = ({ sign_id, sign_video, approveSignVide
|
|||||||
deleteSignVideo();
|
deleteSignVideo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleTypeChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
|
||||||
|
datasetSignVideo(e.target.value);
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getVideo(sign_id, sign_video.id).then((response) => {
|
getVideo(sign_id, sign_video.id).then((response) => {
|
||||||
setVideoBlob(URL.createObjectURL(response))
|
setVideoBlob(URL.createObjectURL(response))
|
||||||
@@ -59,6 +64,17 @@ const SignVideoPlayer: React.FC<Props> = ({ sign_id, sign_video, approveSignVide
|
|||||||
>
|
>
|
||||||
{!sign_video.approved ? "Accept video" : "Reject video"}
|
{!sign_video.approved ? "Accept video" : "Reject video"}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
<select
|
||||||
|
className="ml-2 border border-gray-300 rounded-lg px-3 py-2"
|
||||||
|
value={sign_video.dataset}
|
||||||
|
onChange={handleTypeChange}
|
||||||
|
>
|
||||||
|
<option value="train">Train</option>
|
||||||
|
<option value="val">Val</option>
|
||||||
|
<option value="test">Test</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
className={`relative mt-4 text-white font-bold py-2 px-4 rounded-full transition-transform duration-200 transform hover:-translate-y-1 hover:scale-105 bg-red-500 `}
|
className={`relative mt-4 text-white font-bold py-2 px-4 rounded-full transition-transform duration-200 transform hover:-translate-y-1 hover:scale-105 bg-red-500 `}
|
||||||
onClick={handleDeleteClick}
|
onClick={handleDeleteClick}
|
||||||
|
|||||||
@@ -57,12 +57,12 @@ const getVideo = async (sign_id: number, video_id: number) => {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const acceptVideo = async (sign_id: number, video_id: number, approved: boolean = false) => {
|
const updateVideo = async (sign_id: number, video_id: number, approved: boolean = false, dataset: string = "train") => {
|
||||||
// get access token from local storage
|
// get access token from local storage
|
||||||
const token = localStorage.getItem('accessToken');
|
const token = localStorage.getItem('accessToken');
|
||||||
|
|
||||||
// make request to get signs
|
// make request to get signs
|
||||||
const response = await axios.patch(`${process.env.REACT_APP_API_URL}/signs/${sign_id}/video/${video_id}/`, { "approved": approved }, {
|
const response = await axios.patch(`${process.env.REACT_APP_API_URL}/signs/${sign_id}/video/${video_id}/`, { "approved": approved, "dataset": dataset }, {
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
"Access-Control-Allow-Methods": '*',
|
"Access-Control-Allow-Methods": '*',
|
||||||
@@ -88,4 +88,4 @@ const deleteVideo = async (sign_id: number, video_id: number) => {
|
|||||||
return response.data;
|
return response.data;
|
||||||
};
|
};
|
||||||
|
|
||||||
export { uploadSignVideo, getThumbail, getVideo, acceptVideo, deleteVideo };
|
export { uploadSignVideo, getThumbail, getVideo, updateVideo, deleteVideo };
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
export interface SignVideo {
|
export interface SignVideo {
|
||||||
id: number;
|
id: number;
|
||||||
approved: boolean;
|
approved: boolean;
|
||||||
|
dataset: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Sign {
|
export interface Sign {
|
||||||
|
|||||||
Reference in New Issue
Block a user