Skip to content

Commit

Permalink
Merge pull request #277 from SkalskiP/develop
Browse files Browse the repository at this point in the history
1.10.0-alpha relese
  • Loading branch information
SkalskiP authored Oct 2, 2022
2 parents 38634f4 + 9404b54 commit 61e5ac5
Show file tree
Hide file tree
Showing 55 changed files with 1,439 additions and 399 deletions.
6 changes: 2 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
# INTELIIJ

# ide
.idea/

# CREATE REACT APP
.vscode/

# dependencies
/node_modules/
Expand Down
44 changes: 21 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@

<h1 align="center">makesense.ai</h1>

<p align="center">
<img width="600" src=".//public/ico/main-image-dark_alter.png" alt="Logo">
<p align="center">
</br>
<img width="100" src=".//public/favicon.png" alt="make sense logo">
</br>
</p>

[makesense.ai][1] is a free-to-use online tool for labeling photos. Thanks to the use of a browser it does not require any complicated installation - just visit the website and you are ready to go. It also doesn't matter which operating system you're running on - we do our best to be truly cross-platform. It is perfect for small computer vision deep learning projects, making the process of preparing a dataset much easier and faster. Prepared labels can be downloaded in one of the multiple supported formats. The application was written in TypeScript and is based on React/Redux duo.
Expand All @@ -15,17 +17,13 @@

You can find out more about our tool from the newly released [documentation][14].

## 💡 Motto

> For AI to be free we need not just Open Source, but also a strong Open Data movement.
Andrew Ng

## 👀 Sneak Peek

<p align="center">
<img width="1000" src=".//examples/demo-base.gif" alt="alfa-demo">
<div align="center">
<p>
<img width="850" src=".//examples/demo-base.gif">
</p>
</div>

**Figure 1.** Basic version of the application - without AI support

Expand All @@ -38,16 +36,19 @@ Andrew Ng

In the future, we also plan to add, among other things, models that classify photos, detect characteristic features of faces as well as whole faces. The engine that drives our AI functionalities is [TensorFlow.js][10] - JS version of the most popular framework for training neural networks. This choice allows us not only to speed up your work but also to care about the privacy of your data, because unlike with other commercial and open source tools, your photos do not have to be transferred to the server. This time AI comes to your device!

<p align="center">
<img width="1000" src=".//examples/demo-ssd.gif" alt="ai-demo">
<div align="center">
<p>
<img width="850" src=".//examples/demo-ssd.gif">
</p>
</div>

**Figure 2.** SSD model - allows you to detect multiple objects, speeding up the bbox labeling process


<p align="center">
<img width="1000" src=".//examples/demo-posenet.gif" alt="ai-demo">
<div align="center">
<p>
<img width="850" src=".//examples/demo-posenet.gif">
</p>
</div>

**Figure 3.** PoseNet model - allows you to detect people's poses in photos, automating point labeling in some usecases

Expand Down Expand Up @@ -138,17 +139,15 @@ You can find examples of export files along with a description and schema on our

We don't store your images, because we don't send them anywhere in the first place.

## 📅 Road Map

Our application is being actively developed. Check out our plans for the near future on our [Wiki][6]. If you have an idea for a new functionality, please hit us on [Twitter][3] and [Gitter][5] or create an issue where you can describe your concept. In the meantime, see what improvements we are planning for you in the future.

## 🚀 Tutorials

If you are just starting your adventure with deep learning and would like to learn and create something cool along the way, [makesense.ai][1] can help you with that. Leverage our bounding box labeling functionality to prepare a data set and use it to train your first state-of-the-art object detection model. Follow [instructions][12] and [examples][13] but most importantly, free your creativity.

<p align="center">
<img width="800" src=".//examples/object_detection_basketball.gif" alt="Object detection tutorial">
<div align="center">
<p>
<img width="850" src=".//examples/object_detection_basketball.gif">
</p>
</div>

**Figure 4.** Detection of players moving around the basketball court, based on <a href="https://research.google.com/youtube8m/">YouTube-8M</a> dataset.

Expand All @@ -160,8 +159,6 @@ If you are just starting your adventure with deep learning and would like to lea
</a>
</p>

Feel free to file [issues](https://github.com/SkalskiP/make-sense/issues) or [pull requests](https://github.com/SkalskiP/make-sense/pulls).

## 💬 Citation

Please cite Make Sense in your publications if this is useful for your research. Here is an example BibTeX entry:
Expand Down Expand Up @@ -193,3 +190,4 @@ This project is licensed under the GPL-3.0 License - see the [LICENSE][2] file f
[12]: https://towardsdatascience.com/chess-rolls-or-basketball-lets-create-a-custom-object-detection-model-ef53028eac7d
[13]: https://github.com/SkalskiP/ILearnDeepLearning.py/tree/master/02_data_science_toolkit/02_yolo_object_detection
[14]: https://skalskip.github.io/make-sense/
[15]: https://github.com/SkalskiP/make-sense/issues
44 changes: 43 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@
"react-redux": "^8.0.2",
"react-spinners": "^0.13.3",
"redux": "^4.2.0",
"uuid": "^8.3.2"
"uuid": "^8.3.2",
"yolov5js": "^1.0.0"
},
"scripts": {
"dev": "vite",
Expand Down
Binary file added public/ico/download.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/ico/twitch-logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified public/ico/upload.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
23 changes: 13 additions & 10 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,14 @@ import NotificationsView from './views/NotificationsView/NotificationsView';
interface IProps {
projectType: ProjectType;
windowSize: ISize;
ObjectDetectorLoaded: boolean;
PoseDetectionLoaded: boolean;
isObjectDetectorLoaded: boolean;
isPoseDetectionLoaded: boolean;
isYOLOV5ObjectDetectorLoaded: boolean;
}

const App: React.FC<IProps> = ({projectType, windowSize, ObjectDetectorLoaded, PoseDetectionLoaded}) => {
const App: React.FC<IProps> = ({
projectType, windowSize, isObjectDetectorLoaded, isPoseDetectionLoaded, isYOLOV5ObjectDetectorLoaded
}) => {
const selectRoute = () => {
if (!!PlatformModel.mobileDeviceData.manufacturer && !!PlatformModel.mobileDeviceData.os)
return <MobileMainView/>;
Expand All @@ -35,23 +38,23 @@ const App: React.FC<IProps> = ({projectType, windowSize, ObjectDetectorLoaded, P
}
}
};

return (
<div className={classNames('App', {'AI': ObjectDetectorLoaded || PoseDetectionLoaded})}
draggable={false}
const isAILoaded = isObjectDetectorLoaded || isPoseDetectionLoaded || isYOLOV5ObjectDetectorLoaded
return (
<div className={classNames('App', {'AI': isAILoaded})} draggable={false}
>
{selectRoute()}
<PopupView/>
<NotificationsView/>
</div>
);
);
};

const mapStateToProps = (state: AppState) => ({
projectType: state.general.projectData.type,
windowSize: state.general.windowSize,
ObjectDetectorLoaded: state.ai.isObjectDetectorLoaded,
PoseDetectionLoaded: state.ai.isPoseDetectorLoaded
isSSDObjectDetectorLoaded: state.ai.isSSDObjectDetectorLoaded,
isPoseDetectorLoaded: state.ai.isPoseDetectorLoaded,
isYOLOV5ObjectDetectorLoaded: state.ai.isYOLOV5ObjectDetectorLoaded
});

export default connect(
Expand Down
50 changes: 0 additions & 50 deletions src/ai/ObjectDetector.ts
Original file line number Diff line number Diff line change
@@ -1,50 +0,0 @@
import '@tensorflow/tfjs-backend-cpu';
import * as cocoSsd from '@tensorflow-models/coco-ssd';
import {DetectedObject, ObjectDetection} from '@tensorflow-models/coco-ssd';
import {store} from '../index';
import {updateObjectDetectorStatus} from '../store/ai/actionCreators';
import {LabelType} from '../data/enums/LabelType';
import {LabelsSelector} from '../store/selectors/LabelsSelector';
import {AIObjectDetectionActions} from '../logic/actions/AIObjectDetectionActions';
import {updateActiveLabelType} from '../store/labels/actionCreators';

export class ObjectDetector {
private static model: ObjectDetection;

public static loadModel(callback?: () => unknown) {
cocoSsd
.load()
.then((model: ObjectDetection) => {
ObjectDetector.model = model;
store.dispatch(updateObjectDetectorStatus(true));
store.dispatch(updateActiveLabelType(LabelType.RECT));
const activeLabelType: LabelType = LabelsSelector.getActiveLabelType();
if (activeLabelType === LabelType.RECT) {
AIObjectDetectionActions.detectRectsForActiveImage();
}
if (callback) {
callback();
}
})
.catch((error) => {
// TODO
throw new Error(error as string);
})
}

public static predict(image: HTMLImageElement, callback?: (predictions: DetectedObject[]) => unknown) {
if (!ObjectDetector.model) return;

ObjectDetector.model
.detect(image)
.then((predictions: DetectedObject[]) => {
if (callback) {
callback(predictions)
}
})
.catch((error) => {
// TODO
throw new Error(error as string);
})
}
}
25 changes: 20 additions & 5 deletions src/ai/PoseDetector.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import '@tensorflow/tfjs-backend-webgl';
import * as posenet from '@tensorflow-models/posenet';
import {PoseNet} from '@tensorflow-models/posenet';
import {Pose} from '@tensorflow-models/posenet';
Expand All @@ -8,6 +7,10 @@ import {AIPoseDetectionActions} from '../logic/actions/AIPoseDetectionActions';
import {LabelType} from '../data/enums/LabelType';
import {LabelsSelector} from '../store/selectors/LabelsSelector';
import {updateActiveLabelType} from '../store/labels/actionCreators';
import {submitNewNotification} from '../store/notifications/actionCreators';
import {NotificationUtil} from '../utils/NotificationUtil';
import {NotificationsDataMap} from '../data/info/NotificationsData';
import {Notification} from '../data/enums/Notification';

export class PoseDetector {
private static model: PoseNet;
Expand All @@ -33,8 +36,14 @@ export class PoseDetector {
}
})
.catch((error) => {
// TODO
throw new Error(error as string);
// TODO: Introduce central logging system like Sentry
store.dispatch(
submitNewNotification(
NotificationUtil.createErrorNotification(
NotificationsDataMap[Notification.MODEL_DOWNLOAD_ERROR]
)
)
)
})
}

Expand All @@ -49,8 +58,14 @@ export class PoseDetector {
}
})
.catch((error) => {
// TODO
throw new Error(error as string);
// TODO: Introduce central logging system like Sentry
store.dispatch(
submitNewNotification(
NotificationUtil.createErrorNotification(
NotificationsDataMap[Notification.MODEL_INFERENCE_ERROR]
)
)
)
})
}
}
Loading

0 comments on commit 61e5ac5

Please sign in to comment.