Compare commits

..

12 Commits

Author SHA1 Message Date
Yonghye Kwon
cb4ab0970a
modify screenshot for ubuntu installation 2023-01-13 12:27:09 +09:00
Yonghye Kwon
ab4c936d16
add installation guide for Ubuntu22.04 2023-01-13 12:24:52 +09:00
Yonghye Kwon
e3eea126e1 checkbox bug fix 2023-01-13 01:08:21 +09:00
Yonghye Kwon
7e92a54550
modify download link 2023-01-10 22:40:32 +09:00
Yonghye Kwon
78fb3a5458
Merge pull request #57 from developer0hye/v1.2
v1.2 README!!!!!!!
2023-01-10 22:16:14 +09:00
Yonghye Kwon
02c0e09b5c
v1.2 README!!!!!!! 2023-01-10 22:15:15 +09:00
Yonghye Kwon
cab3dfcb8f
Merge pull request #56 from e8035669/master
Visualize class names on the bounding box
2023-01-10 21:33:50 +09:00
Yonghye Kwon
cc3a188275 turn on or off visualization function with a check box 2023-01-10 21:32:09 +09:00
Yonghye Kwon
7796b8606d add shortcut for open file button and description for other functions 2023-01-10 21:31:04 +09:00
Yonghye Kwon
588bd80e8a add visualize class names checkbox 2023-01-10 20:54:53 +09:00
Yu-Ren Zhang
065ee35656 Ensure resized image has the same format with the input image. Add drawObjectLabels() to draw all the labels
Signed-off-by: Yu-Ren Zhang <e8035669@gmail.com>
2022-11-07 16:32:27 +08:00
Yu-Ren Zhang
037276bc01 add drawing object box with label
Signed-off-by: Yu-Ren Zhang <e8035669@gmail.com>
2022-11-07 16:32:27 +08:00
7 changed files with 119 additions and 82 deletions

View File

@ -33,11 +33,9 @@ But... I've reinvented one...
It's the **SENSITIVE** image-labeling tool for object detection!
![image](https://user-images.githubusercontent.com/35001605/143729836-b2ee1188-f829-473f-aff0-d13569b3fc39.png)
![image](https://user-images.githubusercontent.com/35001605/211553495-66e81a7d-df00-44ca-82e4-966000cddbd1.png)
![ezgif-5-85c0613befb3](https://user-images.githubusercontent.com/35001605/47693025-3d094900-dc3b-11e8-9d96-ea2f7e37cf7a.gif)
![ezgif-5-c57fe634145b](https://user-images.githubusercontent.com/35001605/47693028-3f6ba300-dc3b-11e8-9e22-70c448d59398.gif)
https://user-images.githubusercontent.com/35001605/211560039-367f27d7-63ab-4342-824e-9f47f2afbc35.mp4
![cut (2)](https://user-images.githubusercontent.com/35001605/143729909-b2da3669-020a-4769-ab1d-2646dd7bbb6b.gif)
@ -54,7 +52,7 @@ But... I've reinvented one...
### For Windows
2. Download [YOLOLabel_20211130_v1.1.1](https://github.com/developer0hye/Yolo_Label/releases/download/v1.1.1/YoloLabel_v1.1.1.zip)
2. Download [YOLOLabel_v1.2.1.zip](https://github.com/developer0hye/Yolo_Label/releases/download/v1.2.1/YoloLabel_v1.2.1.zip)
3. Unzip
@ -62,6 +60,27 @@ But... I've reinvented one...
![image](https://user-images.githubusercontent.com/35001605/111152300-e74b5680-85d3-11eb-8df7-178148548c12.png)
### For Ubuntu 22.04
2. Download [YOLOLabel_v1.2.1.tar](https://github.com/developer0hye/Yolo_Label/releases/download/v1.2.1/YoloLabel_v1.2.1.tar)
3. Unzip and download libraries
```
tar -xvf YoloLabel_v1.2.1.tar
sudo apt update
sudo apt-get install -y libgl1-mesa-dev
sudo apt-get install libxcb-*
sudo apt-get install libxkb*
```
4. Run YoloLabel.sh
```
./YoloLabel.sh
```
![image](https://user-images.githubusercontent.com/35001605/212230332-7e62bc50-7440-45c8-afc3-faebc0b31318.png)
### For macOS
2. Clone or download the source code of this repository
@ -94,7 +113,7 @@ yourMacOS:Yolo_Label you$ ./YoloLabel.app/MacOS/YoloLabel
4. Click the button 'Open Files' and open the folder with the images and the file('*'.names or '*'.txt) with the names of the objects.
![image](https://user-images.githubusercontent.com/35001605/47694149-d20e4100-dc3f-11e8-9d97-fba87a6e1b5a.png)
![image](https://user-images.githubusercontent.com/35001605/211560758-f119f562-9462-4ebe-86fa-a9c169b18993.png)
5. And... Label!... Welcome to Hell... I really hate this work in the world.
@ -128,6 +147,8 @@ To minimize wrist strain when labeling, I adopted the method **"twice left butto
| `D, Space` | Save and Next Image |
| `S` | Next Label <br> ![ezgif-5-f7ee77cd24c3](https://user-images.githubusercontent.com/35001605/47703190-d3049a00-dc62-11e8-846f-5bd91e98bdbc.gif) |
| `W` | Prev Label <br> ![ezgif-5-ee915c66dad8](https://user-images.githubusercontent.com/35001605/47703191-d39d3080-dc62-11e8-800b-986ec214b80c.gif) |
| `O` | Open Files |
| `V` | Visualize Calss Name |
| `Ctrl + S` | Save |
| `Ctrl + C` | Delete all existing bounding boxes in the image |
| `Ctrl + D` | Delete current image |
@ -153,10 +174,13 @@ You can access all image by moving horizontal slider bar. But when you control h
![ezgif-5-53abf38b3387](https://user-images.githubusercontent.com/35001605/47708528-97bd9780-dc71-11e8-94f1-5ee23776d5fe.gif)
# CONCLUSIONS
I've reinvented the wheel.
![dont-reinvent-the-wheel](https://user-images.githubusercontent.com/35001605/47709289-46160c80-dc73-11e8-8ef6-6af3a3c52403.jpg)
# TO DO LISTS
Upload binary file for easy usage for windows and ubuntu
deployment for ubuntu

View File

@ -125,7 +125,8 @@ void label_img::openImage(const QString &qstrImg, bool &ret)
m_inputImg = img.copy();
m_inputImg = m_inputImg.convertToFormat(QImage::Format_RGB888);
m_resized_inputImg = m_inputImg.scaled(this->width(), this->height(),Qt::IgnoreAspectRatio,Qt::SmoothTransformation);
m_resized_inputImg = m_inputImg.scaled(this->width(), this->height(),Qt::IgnoreAspectRatio,Qt::SmoothTransformation)
.convertToFormat(QImage::Format_RGB888);
m_bLabelingStarted = false;
@ -148,7 +149,8 @@ void label_img::showImage()
if(m_inputImg.isNull()) return;
if(m_resized_inputImg.width() != this->width() or m_resized_inputImg.height() != this->height())
{
m_resized_inputImg = m_inputImg.scaled(this->width(), this->height(),Qt::IgnoreAspectRatio,Qt::SmoothTransformation);
m_resized_inputImg = m_inputImg.scaled(this->width(), this->height(),Qt::IgnoreAspectRatio,Qt::SmoothTransformation)
.convertToFormat(QImage::Format_RGB888);
}
QImage img = m_resized_inputImg;
@ -156,6 +158,11 @@ void label_img::showImage()
gammaTransform(img);
QPainter painter(&img);
QFont font = painter.font();
int fontSize = 16, xMargin = 5, yMargin = 2;
font.setPixelSize(fontSize);
font.setBold(true);
painter.setFont(font);
int penThick = 3;
@ -164,6 +171,8 @@ void label_img::showImage()
drawCrossLine(painter, crossLineColor, penThick);
drawFocusedObjectBox(painter, Qt::magenta, penThick);
drawObjectBoxes(painter, penThick);
if(m_bVisualizeClassName)
drawObjectLabels(painter, penThick, fontSize, xMargin, yMargin);
this->setPixmap(QPixmap::fromImage(img));
}
@ -279,6 +288,36 @@ void label_img::drawObjectBoxes(QPainter& painter, int thickWidth)
}
}
void label_img::drawObjectLabels(QPainter& painter, int thickWidth, int fontPixelSize, int xMargin, int yMargin)
{
QFontMetrics fontMetrics = painter.fontMetrics();
QPen blackPen;
for(ObjectLabelingBox boundingbox: m_objBoundingBoxes)
{
QColor labelColor = m_drawObjectBoxColor.at(boundingbox.label);
QRect rectUi = cvtRelativeToAbsoluteRectInUi(boundingbox.box);
QRect labelRect = fontMetrics.boundingRect(m_objList.at(boundingbox.label));
if (rectUi.top() > fontPixelSize + yMargin * 2 + thickWidth + 1) {
labelRect.moveTo(rectUi.topLeft() + QPoint(-thickWidth / 2, -(fontPixelSize + yMargin * 2 + thickWidth + 1)));
labelRect.adjust(0, 0, xMargin * 2, yMargin * 2);
} else {
labelRect.moveTo(rectUi.topLeft() + QPoint(-thickWidth / 2, 0));
labelRect.adjust(0, 0, xMargin * 2, yMargin * 2);
}
painter.fillRect(labelRect, labelColor);
if (qGray(m_drawObjectBoxColor.at(boundingbox.label).rgb()) > 120) {
blackPen.setColor(QColorConstants::Black);
} else {
blackPen.setColor(QColorConstants::White);
}
painter.setPen(blackPen);
painter.drawText(labelRect.topLeft() + QPoint(xMargin, yMargin + fontPixelSize), m_objList.at(boundingbox.label));
}
}
void label_img::gammaTransform(QImage &image)
{
uchar* bits = image.bits();

View File

@ -25,6 +25,7 @@ public:
void mouseReleaseEvent(QMouseEvent *ev);
QVector<QColor> m_drawObjectBoxColor;
QStringList m_objList;
int m_uiX;
int m_uiY;
@ -33,6 +34,7 @@ public:
int m_imgY;
bool m_bLabelingStarted;
bool m_bVisualizeClassName;
static QColor BOX_COLORS[10];
@ -86,6 +88,7 @@ private:
void drawCrossLine(QPainter& , QColor , int thickWidth = 3);
void drawFocusedObjectBox(QPainter& , Qt::GlobalColor , int thickWidth = 3);
void drawObjectBoxes(QPainter& , int thickWidth = 3);
void drawObjectLabels(QPainter& , int thickWidth = 3, int fontPixelSize = 14, int xMargin = 5, int yMargin = 2);
void gammaTransform(QImage& image);
void removeFocusedObjectBox(QPointF);
};

View File

@ -4,7 +4,7 @@
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w(nullptr, argc, argv);
MainWindow w;
w.show();
return a.exec();
}

View File

@ -16,7 +16,7 @@ using std::ofstream;
using std::ifstream;
using std::string;
MainWindow::MainWindow(QWidget *parent, int argc, char *argv[]) :
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
@ -34,15 +34,6 @@ MainWindow::MainWindow(QWidget *parent, int argc, char *argv[]) :
connect(new QShortcut(QKeySequence(Qt::Key_Delete), this), SIGNAL(activated()), this, SLOT(remove_img()));
init_table_widget();
if(argc == 3)
{
std::cout << "Dataset Path: " << argv[1] << std::endl;
std::cout << "Label List File Path: " << argv[2] << std::endl;
open_img_dir(argv[1]);
open_obj_file(argv[2]);
init();
}
}
MainWindow::~MainWindow()
@ -207,7 +198,7 @@ void MainWindow::remove_img()
}
else if( m_imgIndex == m_imgList.size())
{
m_imgIndex --;
m_imgIndex--;
}
goto_img(m_imgIndex);
@ -259,6 +250,7 @@ void MainWindow::load_label_list_data(QString qstrLabelListFile)
ui->label_image->m_drawObjectBoxColor.push_back(labelColor);
}
ui->label_image->m_objList = m_objList;
}
}
@ -343,33 +335,6 @@ void MainWindow::open_img_dir(bool& ret)
}
}
void MainWindow::open_img_dir(char* img_dir)
{
QString imgDir(img_dir);
QDir dir(imgDir);
QCollator collator;
collator.setNumericMode(true);
QStringList fileList = dir.entryList(
QStringList() << "*.jpg" << "*.JPG" << "*.png" << "*.bmp",
QDir::Files);
std::sort(fileList.begin(), fileList.end(), collator);
if(fileList.empty())
{
pjreddie_style_msgBox(QMessageBox::Critical,"Error", "This folder is empty");
}
else
{
m_imgDir = imgDir;
m_imgList = fileList;
for(QString& str: m_imgList)
str = m_imgDir + "/" + str;
}
}
void MainWindow::open_obj_file(bool& ret)
{
pjreddie_style_msgBox(QMessageBox::Information,"Help", "Step 2. Open Your Label List File(*.txt or *.names)");
@ -396,29 +361,6 @@ void MainWindow::open_obj_file(bool& ret)
}
}
void MainWindow::open_obj_file(char* file)
{
QString opened_dir;
if(m_imgDir.size() > 0) opened_dir = m_imgDir;
else opened_dir = QDir::currentPath();
QString fileLabelList(file);
if(fileLabelList.size() == 0)
{
pjreddie_style_msgBox(QMessageBox::Critical,"Error", "LabelList file is not opened()");
}
else
{
load_label_list_data(fileLabelList);
}
}
void MainWindow::reupdate_img_list()
{
}
void MainWindow::wheelEvent(QWheelEvent *ev)
{
if(ev->angleDelta().y() > 0) // up Wheel
@ -533,3 +475,9 @@ void MainWindow::on_horizontalSlider_contrast_sliderMoved(int value)
ui->label_image->setContrastGamma(percentageToGamma);
ui->label_contrast->setText(QString("Contrast(%) ") + QString::number(int(valueToPercentage * 100.)));
}
void MainWindow::on_checkBox_visualize_class_name_clicked(bool checked)
{
ui->label_image->m_bVisualizeClassName = checked;
ui->label_image->showImage();
}

View File

@ -18,15 +18,11 @@ class MainWindow : public QMainWindow
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr, int argc=0, char *argv[]=nullptr);
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_pushButton_open_files_clicked();
// void on_pushButton_change_dir_clicked();
// void on_pushButton_save_clicked();
// void on_pushButton_remove_clicked();
void on_pushButton_prev_clicked();
void on_pushButton_next_clicked();
@ -48,6 +44,8 @@ private slots:
void on_horizontalSlider_contrast_sliderMoved(int value);
void on_checkBox_visualize_class_name_clicked(bool checked);
private:
void init();
void init_table_widget();
@ -71,11 +69,6 @@ private:
void open_img_dir(bool&);
void open_obj_file(bool&);
void open_img_dir(char *);
void open_obj_file(char *);
void reupdate_img_list();
Ui::MainWindow *ui;
QString m_imgDir;

View File

@ -57,7 +57,7 @@
</size>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<item row="3" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<layout class="QVBoxLayout" name="verticalLayout">
@ -77,6 +77,7 @@
</property>
<property name="font">
<font>
<family>Arial</family>
<pointsize>18</pointsize>
<weight>75</weight>
<bold>true</bold>
@ -106,7 +107,7 @@ border-color: rgb(0, 255, 255);}
<number>3</number>
</property>
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Open a Dataset Directory...&lt;/p&gt;&lt;p&gt;D: Next Image&lt;/p&gt;&lt;p&gt;A: Prev Image&lt;/p&gt;&lt;p&gt;&lt;br/&gt;Ctrl + S: Save&lt;/p&gt;&lt;p&gt;Ctrl + D: Delete an Image&lt;br/&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Open a Dataset Directory...&lt;/p&gt;&lt;p&gt;D: Next Image&lt;/p&gt;&lt;p&gt;A: Prev Image&lt;/p&gt;&lt;p&gt;S: Next Class&lt;/p&gt;&lt;p&gt;W: Prev Class&lt;/p&gt;&lt;p&gt;V: Visualize Class Name&lt;/p&gt;&lt;p&gt;O: Open Files&lt;br/&gt;Ctrl + S: Save&lt;/p&gt;&lt;p&gt;Ctrl + D: Delete an Image&lt;br/&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="scaledContents">
<bool>true</bool>
@ -396,6 +397,9 @@ border-color: rgb(0, 255, 255);</string>
<property name="text">
<string>Open Files</string>
</property>
<property name="shortcut">
<string>O</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
@ -575,6 +579,32 @@ QTableView {
</item>
</layout>
</item>
<item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_6">
<item>
<widget class="QCheckBox" name="checkBox_visualize_class_name">
<property name="font">
<font>
<family>Arial</family>
<pointsize>12</pointsize>
<underline>false</underline>
<strikeout>false</strikeout>
</font>
</property>
<property name="styleSheet">
<string notr="true">background-color : rgb(0, 0, 17);color : rgb(0, 255, 255);
</string>
</property>
<property name="text">
<string>Visualize Class Name</string>
</property>
<property name="shortcut">
<string>V</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menuBar">