move PPOCRLabel to PFCCLab/PPOCRLabel (#12104)
|
@ -1,35 +0,0 @@
|
|||
# ex: set ts=8 noet:
|
||||
|
||||
all: qt5 test
|
||||
|
||||
test: testpy3
|
||||
|
||||
testpy2:
|
||||
python -m unittest discover tests
|
||||
|
||||
testpy3:
|
||||
python3 -m unittest discover tests
|
||||
|
||||
qt4: qt4py2
|
||||
|
||||
qt5: qt5py3
|
||||
|
||||
qt4py2:
|
||||
pyrcc4 -py2 -o libs/resources.py resources.qrc
|
||||
|
||||
qt4py3:
|
||||
pyrcc4 -py3 -o libs/resources.py resources.qrc
|
||||
|
||||
qt5py3:
|
||||
pyrcc5 -o libs/resources.py resources.qrc
|
||||
|
||||
clean:
|
||||
rm -rf ~/.labelImgSettings.pkl *.pyc dist labelImg.egg-info __pycache__ build
|
||||
|
||||
pip_upload:
|
||||
python3 setup.py upload
|
||||
|
||||
long_description:
|
||||
restview --long-description
|
||||
|
||||
.PHONY: all
|
|
@ -1,281 +0,0 @@
|
|||
English | [简体中文](README_ch.md)
|
||||
|
||||
# PPOCRLabelv2
|
||||
|
||||
PPOCRLabelv2 is a semi-automatic graphic annotation tool suitable for OCR field, with built-in PP-OCR model to automatically detect and re-recognize data. It is written in Python3 and PyQT5, supporting rectangular box, table, irregular text and key information annotation modes. Annotations can be directly used for the training of PP-OCR detection and recognition models.
|
||||
|
||||
| regular text annotation | table annotation |
|
||||
| :-------------------------------------------------: | :--------------------------------------------: |
|
||||
| <img src="./data/gif/steps_en.gif" width="80%"/> | <img src="./data/gif/table.gif" width="100%"/> |
|
||||
| **irregular text annotation** | **key information annotation** |
|
||||
| <img src="./data/gif/multi-point.gif" width="80%"/> | <img src="./data/gif/kie.gif" width="100%"/> |
|
||||
|
||||
### Recent Update
|
||||
|
||||
- 2022.05: Add table annotations, follow `2.2 Table Annotations` for more information (by [whjdark](https://github.com/peterh0323); [Evezerest](https://github.com/Evezerest))
|
||||
- 2022.02:(by [PeterH0323](https://github.com/peterh0323) )
|
||||
- Add KIE Mode by using `--kie`, for [detection + identification + keyword extraction] labeling.
|
||||
- Improve user experience: prompt for the number of files and labels, optimize interaction, and fix bugs such as only use CPU when inference
|
||||
- New functions: Support using `C` or `X` to rotate box.
|
||||
- 2021.11.17:
|
||||
- Support install and start PPOCRLabel through the whl package (by [d2623587501](https://github.com/d2623587501))
|
||||
- Dataset segmentation: Divide the annotation file into training, verification and testing parts (refer to section 3.5 below, by [MrCuiHao](https://github.com/MrCuiHao))
|
||||
- 2021.8.11:
|
||||
- New functions: Open the dataset folder, image rotation (Note: Please delete the label box before rotating the image) (by [Wei-JL](https://github.com/Wei-JL))
|
||||
- Added shortcut key description (Help-Shortcut Key), repaired the direction shortcut key movement function under batch processing (by [d2623587501](https://github.com/d2623587501))
|
||||
- 2021.2.5: New batch processing and undo functions (by [Evezerest](https://github.com/Evezerest)):
|
||||
- **Batch processing function**: Press and hold the Ctrl key to select the box, you can move, copy, and delete in batches.
|
||||
- **Undo function**: In the process of drawing a four-point label box or after editing the box, press Ctrl+Z to undo the previous operation.
|
||||
- Fix image rotation and size problems, optimize the process of editing the mark frame (by [ninetailskim](https://github.com/ninetailskim)、 [edencfc](https://github.com/edencfc)).
|
||||
- 2021.1.11: Optimize the labeling experience (by [edencfc](https://github.com/edencfc)),
|
||||
- Users can choose whether to pop up the label input dialog after drawing the detection box in "View - Pop-up Label Input Dialog".
|
||||
- The recognition result scrolls synchronously when users click related detection box.
|
||||
- Click to modify the recognition result.(If you can't change the result, please switch to the system default input method, or switch back to the original input method again)
|
||||
- 2020.12.18: Support re-recognition of a single label box (by [ninetailskim](https://github.com/ninetailskim) ), perfect shortcut keys.
|
||||
|
||||
|
||||
|
||||
## 1. Installation and Run
|
||||
|
||||
### 1.1 Install PaddlePaddle
|
||||
|
||||
```bash
|
||||
pip3 install --upgrade pip
|
||||
|
||||
# If you have cuda9 or cuda10 installed on your machine, please run the following command to install
|
||||
python3 -m pip install paddlepaddle-gpu -i https://mirror.baidu.com/pypi/simple
|
||||
|
||||
# If you only have cpu on your machine, please run the following command to install
|
||||
python3 -m pip install paddlepaddle -i https://mirror.baidu.com/pypi/simple
|
||||
```
|
||||
|
||||
For more software version requirements, please refer to the instructions in [Installation Document](https://www.paddlepaddle.org.cn/install/quick) for operation.
|
||||
|
||||
### 1.2 Install and Run PPOCRLabel
|
||||
|
||||
PPOCRLabel can be started in two ways: whl package and Python script. The whl package form is more convenient to start, and the python script to start is convenient for secondary development.
|
||||
|
||||
#### Windows
|
||||
|
||||
```bash
|
||||
pip install PPOCRLabel # install
|
||||
|
||||
# Select label mode and run
|
||||
PPOCRLabel # [Normal mode] for [detection + recognition] labeling
|
||||
PPOCRLabel --kie True # [KIE mode] for [detection + recognition + keyword extraction] labeling
|
||||
```
|
||||
|
||||
> If you getting this error `OSError: [WinError 126] The specified module could not be found` when you install shapely on windows. Please try to download Shapely whl file using http://www.lfd.uci.edu/~gohlke/pythonlibs/#shapely.
|
||||
>
|
||||
> Reference: [Solve shapely installation on windows](https://stackoverflow.com/questions/44398265/install-shapely-oserror-winerror-126-the-specified-module-could-not-be-found)
|
||||
>
|
||||
|
||||
#### Ubuntu Linux
|
||||
|
||||
```bash
|
||||
pip3 install PPOCRLabel
|
||||
pip3 install trash-cli
|
||||
|
||||
# Select label mode and run
|
||||
PPOCRLabel # [Normal mode] for [detection + recognition] labeling
|
||||
PPOCRLabel --kie True # [KIE mode] for [detection + recognition + keyword extraction] labeling
|
||||
```
|
||||
|
||||
#### MacOS
|
||||
```bash
|
||||
pip3 install PPOCRLabel
|
||||
pip3 install opencv-contrib-python-headless==4.2.0.32
|
||||
|
||||
# Select label mode and run
|
||||
PPOCRLabel # [Normal mode] for [detection + recognition] labeling
|
||||
PPOCRLabel --kie True # [KIE mode] for [detection + recognition + keyword extraction] labeling
|
||||
```
|
||||
|
||||
#### 1.2.2 Run PPOCRLabel by Python Script
|
||||
If you modify the PPOCRLabel file (for example, specifying a new built-in model), it will be more convenient to see the results by running the Python script. If you still want to start with the whl package, you need to uninstall the whl package in the current environment and then recompile it according to the next section.
|
||||
|
||||
```bash
|
||||
cd ./PPOCRLabel # Switch to the PPOCRLabel directory
|
||||
|
||||
# Select label mode and run
|
||||
python PPOCRLabel.py # [Normal mode] for [detection + recognition] labeling
|
||||
python PPOCRLabel.py --kie True # [KIE mode] for [detection + recognition + keyword extraction] labeling
|
||||
```
|
||||
|
||||
#### 1.2.3 Build and Install the Whl Package Locally
|
||||
Compile and install a new whl package, where 0.0.0 is the version number, you can specify the new version in 'setup.py'.
|
||||
```bash
|
||||
cd ./PPOCRLabel
|
||||
python3 setup.py bdist_wheel
|
||||
pip3 install dist/PPOCRLabel-0.0.0-py2.py3-none-any.whl
|
||||
```
|
||||
|
||||
|
||||
## 2. Usage
|
||||
|
||||
### 2.1 Steps
|
||||
|
||||
1. Build and launch using the instructions above.
|
||||
|
||||
2. Click 'Open Dir' in Menu/File to select the folder of the picture.<sup>[1]</sup>
|
||||
|
||||
3. Click 'Auto recognition', use PP-OCR model to automatically annotate images which marked with 'X' <sup>[2]</sup>before the file name.
|
||||
|
||||
4. Create Box:
|
||||
|
||||
4.1 Click 'Create RectBox' or press 'W' in English keyboard mode to draw a new rectangle detection box. Click and release left mouse to select a region to annotate the text area.
|
||||
|
||||
4.2 Press 'Q' to enter four-point labeling mode which enables you to create any four-point shape by clicking four points with the left mouse button in succession and DOUBLE CLICK the left mouse as the signal of labeling completion.
|
||||
|
||||
5. After the marking frame is drawn, the user clicks "OK", and the detection frame will be pre-assigned a "TEMPORARY" label.
|
||||
|
||||
6. Click 're-Recognition', model will rewrite ALL recognition results in ALL detection box<sup>[3]</sup>.
|
||||
|
||||
7. Single click the result in 'recognition result' list to manually change inaccurate recognition results.
|
||||
|
||||
8. **Click "Check", the image status will switch to "√",then the program automatically jump to the next.**
|
||||
|
||||
9. Click "Delete Image", and the image will be deleted to the recycle bin.
|
||||
|
||||
10. Labeling result: the user can export the label result manually through the menu "File - Export Label", while the program will also export automatically if "File - Auto export Label Mode" is selected. The manually checked label will be stored in *Label.txt* under the opened picture folder. Click "File"-"Export Recognition Results" in the menu bar, the recognition training data of such pictures will be saved in the *crop_img* folder, and the recognition label will be saved in *rec_gt.txt*<sup>[4]</sup>.
|
||||
|
||||
### 2.2 Table Annotation
|
||||
The table annotation is aimed at extracting the structure of the table in a picture and converting it to Excel format,
|
||||
so the annotation needs to be done simultaneously with external software to edit Excel.
|
||||
In PPOCRLabel, complete the text information labeling (text and position), complete the table structure information
|
||||
labeling in the Excel file, the recommended steps are:
|
||||
|
||||
1. Table annotation: After opening the table picture, click on the `Table Recognition` button in the upper right corner of PPOCRLabel, which will call the table recognition model in PP-Structure to automatically label
|
||||
the table and pop up Excel at the same time.
|
||||
|
||||
2. Change the recognition result: **label each cell** (i.e. the text in a cell is marked as a box). Right click on the box and click on `Cell Re-recognition`.
|
||||
You can use the model to automatically recognise the text within a cell.
|
||||
|
||||
3. Mark the table structure: for each cell contains the text, **mark as any identifier (such as `1`) in Excel**, to ensure that the merged cell structure is same as the original picture.
|
||||
|
||||
> Note: If there are blank cells in the table, you also need to mark them with a bounding box so that the total number of cells is the same as in the image.
|
||||
|
||||
4. ***Adjust cell order:*** Click on the menu `View` - `Show Box Number` to show the box ordinal numbers, and drag all the results under the 'Recognition Results' column on the right side of the software interface to make the box numbers are arranged from left to right, top to bottom
|
||||
|
||||
5. Export JSON format annotation: close all Excel files corresponding to table images, click `File`-`Export Table Label` to obtain `gt.txt` annotation results.
|
||||
|
||||
### 2.3 Note
|
||||
|
||||
[1] PPOCRLabel uses the opened folder as the project. After opening the image folder, the picture will not be displayed in the dialog. Instead, the pictures under the folder will be directly imported into the program after clicking "Open Dir".
|
||||
|
||||
[2] The image status indicates whether the user has saved the image manually. If it has not been saved manually it is "X", otherwise it is "√", PPOCRLabel will not relabel pictures with a status of "√".
|
||||
|
||||
[3] After clicking "Re-recognize", the model will overwrite ALL recognition results in the picture. Therefore, if the recognition result has been manually changed before, it may change after re-recognition.
|
||||
|
||||
[4] The files produced by PPOCRLabel can be found under the opened picture folder including the following, please do not manually change the contents, otherwise it will cause the program to be abnormal.
|
||||
|
||||
| File name | Description |
|
||||
| :-----------: | :----------------------------------------------------------: |
|
||||
| Label.txt | The detection label file can be directly used for PP-OCR detection model training. After the user saves 5 label results, the file will be automatically exported. It will also be written when the user closes the application or changes the file folder. |
|
||||
| fileState.txt | The picture status file save the image in the current folder that has been manually confirmed by the user. |
|
||||
| Cache.cach | Cache files to save the results of model recognition. |
|
||||
| rec_gt.txt | The recognition label file, which can be directly used for PP-OCR identification model training, is generated after the user clicks on the menu bar "File"-"Export recognition result". |
|
||||
| crop_img | The recognition data, generated at the same time with *rec_gt.txt* |
|
||||
|
||||
|
||||
|
||||
## 3. Explanation
|
||||
|
||||
### 3.1 Shortcut keys
|
||||
|
||||
| Shortcut keys | Description |
|
||||
|--------------------------|--------------------------------------------------|
|
||||
| Ctrl + Shift + R | Re-recognize all the labels of the current image |
|
||||
| W | Create a rect box |
|
||||
| Q | Create a multi-points box |
|
||||
| X | Rotate the box anti-clockwise |
|
||||
| C | Rotate the box clockwise |
|
||||
| Ctrl + E | Edit label of the selected box |
|
||||
| Ctrl + X | Change key class of the box when enable `--kie` |
|
||||
| Ctrl + R | Re-recognize the selected box |
|
||||
| Ctrl + C | Copy and paste the selected box |
|
||||
| Ctrl + Left Mouse Button | Multi select the label box |
|
||||
| Backspace | Delete the selected box |
|
||||
| Ctrl + V | Check image |
|
||||
| Ctrl + Shift + d | Delete image |
|
||||
| D | Next image |
|
||||
| A | Previous image |
|
||||
| Ctrl++ | Zoom in |
|
||||
| Ctrl-- | Zoom out |
|
||||
| ↑→↓← | Move selected box |
|
||||
|
||||
### 3.2 Built-in Model
|
||||
|
||||
- Default model: PPOCRLabel uses the Chinese and English ultra-lightweight OCR model in PaddleOCR by default, supports Chinese, English and number recognition, and multiple language detection.
|
||||
|
||||
- Model language switching: Changing the built-in model language is supportable by clicking "PaddleOCR"-"Choose OCR Model" in the menu bar. Currently supported languagesinclude French, German, Korean, and Japanese.
|
||||
For specific model download links, please refer to [PaddleOCR Model List](https://github.com/PaddlePaddle/PaddleOCR/blob/release/2.6/doc/doc_en/models_list_en.md)
|
||||
|
||||
- **Custom Model**: If users want to replace the built-in model with their own inference model, they can follow the [Custom Model Code Usage](https://github.com/PaddlePaddle/PaddleOCR/blob/release/2.6/doc/doc_en/whl_en.md#31-use-by-code) by modifying PPOCRLabel.py for [Instantiation of PaddleOCR class](https://github.com/PaddlePaddle/PaddleOCR/blob/release/2.6/PPOCRLabel/PPOCRLabel.py#L97) :
|
||||
|
||||
add parameter `det_model_dir` in `self.ocr = PaddleOCR(use_pdserving=False, use_angle_cls=True, det=True, cls=True, use_gpu=gpu, lang=lang) `
|
||||
|
||||
### 3.3 Export Label Result
|
||||
|
||||
PPOCRLabel supports three ways to export Label.txt
|
||||
|
||||
- Automatically export: After selecting "File - Auto Export Label Mode", the program will automatically write the annotations into Label.txt every time the user confirms an image. If this option is not turned on, it will be automatically exported after detecting that the user has manually checked 5 images.
|
||||
|
||||
> The automatically export mode is turned off by default
|
||||
|
||||
- Manual export: Click "File-Export Marking Results" to manually export the label.
|
||||
|
||||
- Close application export
|
||||
|
||||
### 3.4 Dataset division
|
||||
|
||||
- Enter the following command in the terminal to execute the dataset division script:
|
||||
|
||||
```
|
||||
cd ./PPOCRLabel # Change the directory to the PPOCRLabel folder
|
||||
python gen_ocr_train_val_test.py --trainValTestRatio 6:2:2 --datasetRootPath ../train_data
|
||||
```
|
||||
|
||||
Parameter Description:
|
||||
|
||||
- `trainValTestRatio` is the division ratio of the number of images in the training set, validation set, and test set, set according to your actual situation, the default is `6:2:2`
|
||||
|
||||
- `datasetRootPath` is the storage path of the complete dataset labeled by PPOCRLabel. The default path is `PaddleOCR/train_data` .
|
||||
```
|
||||
|-train_data
|
||||
|-crop_img
|
||||
|- word_001_crop_0.png
|
||||
|- word_002_crop_0.jpg
|
||||
|- word_003_crop_0.jpg
|
||||
| ...
|
||||
| Label.txt
|
||||
| rec_gt.txt
|
||||
|- word_001.png
|
||||
|- word_002.jpg
|
||||
|- word_003.jpg
|
||||
| ...
|
||||
```
|
||||
|
||||
### 3.5 Error message
|
||||
|
||||
- If paddleocr is installed with whl, it has a higher priority than calling PaddleOCR class with paddleocr.py, which may cause an exception if whl package is not updated.
|
||||
|
||||
- For Linux users, if you get an error starting with **objc[XXXXX]** when opening the software, it proves that your opencv version is too high. It is recommended to install version 4.2:
|
||||
|
||||
```
|
||||
pip install opencv-python==4.2.0.32
|
||||
```
|
||||
- If you get an error starting with **Missing string id **,you need to recompile resources:
|
||||
```
|
||||
pyrcc5 -o libs/resources.py resources.qrc
|
||||
```
|
||||
- If you get an error ``` module 'cv2' has no attribute 'INTER_NEAREST'```, you need to delete all opencv related packages first, and then reinstall the 4.2.0.32 version of headless opencv
|
||||
```
|
||||
pip install opencv-contrib-python-headless==4.2.0.32
|
||||
```
|
||||
|
||||
|
||||
|
||||
### 4. Related
|
||||
|
||||
1.[Tzutalin. LabelImg. Git code (2015)](https://github.com/tzutalin/labelImg)
|
|
@ -1,264 +0,0 @@
|
|||
[English](README.md) | 简体中文
|
||||
|
||||
# PPOCRLabelv2
|
||||
|
||||
PPOCRLabel是一款适用于OCR领域的半自动化图形标注工具,内置PP-OCR模型对数据自动标注和重新识别。使用Python3和PyQT5编写,支持矩形框标注、表格标注、不规则文本标注、关键信息标注模式,导出格式可直接用于PaddleOCR检测和识别模型的训练。
|
||||
|
||||
| 常规标注 | 表格标注 |
|
||||
| :-------------------------------------------------: | :--------------------------------------------: |
|
||||
| <img src="./data/gif/steps_en.gif" width="80%"/> | <img src="./data/gif/table.gif" width="100%"/> |
|
||||
| **不规则文本标注** | **关键信息标注** |
|
||||
| <img src="./data/gif/multi-point.gif" width="80%"/> | <img src="./data/gif/kie.gif" width="100%"/> |
|
||||
|
||||
#### 近期更新
|
||||
- 2022.05:**新增表格标注**,使用方法见下方`2.2 表格标注`(by [whjdark](https://github.com/peterh0323); [Evezerest](https://github.com/Evezerest))
|
||||
- 2022.02:**新增关键信息标注**、优化标注体验(by [PeterH0323](https://github.com/peterh0323) )
|
||||
- 新增:使用 `--kie` 进入 KIE 功能,用于打【检测+识别+关键字提取】的标签
|
||||
- 提升用户体验:新增文件与标记数目提示、优化交互、修复gpu使用等问题。
|
||||
- 新增功能:使用 `C` 和 `X` 对标记框进行旋转。
|
||||
- 2021.11.17:
|
||||
- 新增支持通过whl包安装和启动PPOCRLabel(by [d2623587501](https://github.com/d2623587501))
|
||||
- 标注数据集切分:对标注数据进行训练、验证与测试集划分(参考下方3.5节,by [MrCuiHao](https://github.com/MrCuiHao))
|
||||
- 2021.8.11:
|
||||
- 新增功能:打开数据所在文件夹、右键图像旋转90度(注意:旋转前的图片上不能存在标记框,by [Wei-JL](https://github.com/Wei-JL))
|
||||
- 新增快捷键说明(帮助-快捷键)、修复批处理下的方向快捷键移动功能(by [d2623587501](https://github.com/d2623587501))
|
||||
- 2021.2.5:新增批处理与撤销功能(by [Evezerest](https://github.com/Evezerest))
|
||||
- **批处理功能**:按住Ctrl键选择标记框后可批量移动、复制、删除、重新识别。
|
||||
- **撤销功能**:在绘制四点标注框过程中或对框进行编辑操作后,按下Ctrl+Z可撤销上一部操作。
|
||||
- 修复图像旋转和尺寸问题、优化编辑标记框过程(by [ninetailskim](https://github.com/ninetailskim)、 [edencfc](https://github.com/edencfc))
|
||||
- 2021.1.11:优化标注体验(by [edencfc](https://github.com/edencfc)):
|
||||
- 用户可在“视图 - 弹出标记输入框”选择在画完检测框后标记输入框是否弹出。
|
||||
- 识别结果与检测框同步滚动。
|
||||
- 识别结果更改为单击修改。(如果无法修改,请切换为系统自带输入法,或再次切回原输入法)
|
||||
- 2020.12.18: 支持对单个标记框进行重新识别(by [ninetailskim](https://github.com/ninetailskim)),完善快捷键。
|
||||
|
||||
如果您对完善工具有不一样的想法,欢迎通过[社区常规赛](https://github.com/PaddlePaddle/PaddleOCR/issues/4982)报名相关更改,获得积分兑换奖励。
|
||||
|
||||
|
||||
|
||||
## 1. 安装与运行
|
||||
|
||||
### 1.1 安装PaddlePaddle
|
||||
```bash
|
||||
pip3 install --upgrade pip
|
||||
|
||||
# 如果您的机器安装的是CUDA9或CUDA10,请运行以下命令安装
|
||||
python3 -m pip install paddlepaddle-gpu -i https://mirror.baidu.com/pypi/simple
|
||||
|
||||
# 如果您的机器是CPU,请运行以下命令安装
|
||||
python3 -m pip install paddlepaddle -i https://mirror.baidu.com/pypi/simple
|
||||
```
|
||||
|
||||
更多的版本需求,请参照[安装文档](https://www.paddlepaddle.org.cn/install/quick)中的说明进行操作。
|
||||
|
||||
### 1.2 安装与运行PPOCRLabel
|
||||
|
||||
PPOCRLabel可通过whl包与Python脚本两种方式启动,whl包形式启动更加方便,python脚本启动便于二次开发
|
||||
|
||||
#### 1.2.1 通过whl包安装与运行
|
||||
|
||||
##### Windows
|
||||
|
||||
```bash
|
||||
pip install PPOCRLabel # 安装
|
||||
|
||||
# 选择标签模式来启动
|
||||
PPOCRLabel --lang ch # 启动【普通模式】,用于打【检测+识别】场景的标签
|
||||
PPOCRLabel --lang ch --kie True # 启动 【KIE 模式】,用于打【检测+识别+关键字提取】场景的标签
|
||||
```
|
||||
> 注意:通过whl包安装PPOCRLabel会自动下载 `paddleocr` whl包,其中shapely依赖可能会出现 `[winRrror 126] 找不到指定模块的问题。` 的错误,建议从[这里](https://www.lfd.uci.edu/~gohlke/pythonlibs/#shapely)下载并安装
|
||||
##### Ubuntu Linux
|
||||
|
||||
```bash
|
||||
pip3 install PPOCRLabel
|
||||
pip3 install trash-cli
|
||||
|
||||
# 选择标签模式来启动
|
||||
PPOCRLabel --lang ch # 启动【普通模式】,用于打【检测+识别】场景的标签
|
||||
PPOCRLabel --lang ch --kie True # 启动 【KIE 模式】,用于打【检测+识别+关键字提取】场景的标签
|
||||
```
|
||||
|
||||
##### MacOS
|
||||
```bash
|
||||
pip3 install PPOCRLabel
|
||||
pip3 install opencv-contrib-python-headless==4.2.0.32 # 如果下载过慢请添加"-i https://mirror.baidu.com/pypi/simple"
|
||||
|
||||
# 选择标签模式来启动
|
||||
PPOCRLabel --lang ch # 启动【普通模式】,用于打【检测+识别】场景的标签
|
||||
PPOCRLabel --lang ch --kie True # 启动 【KIE 模式】,用于打【检测+识别+关键字提取】场景的标签
|
||||
```
|
||||
|
||||
> 如果上述安装出现问题,可以参考3.6节 错误提示
|
||||
|
||||
#### 1.2.2 通过Python脚本运行PPOCRLabel
|
||||
|
||||
如果您对PPOCRLabel文件有所更改(例如指定新的内置模型),通过Python脚本运行会更加方便的看到更改的结果。如果仍然需要通过whl包启动,则需要先卸载当前环境中的whl包,然后参考下节重新编译whl包。
|
||||
|
||||
```bash
|
||||
cd ./PPOCRLabel # 切换到PPOCRLabel目录
|
||||
python PPOCRLabel.py --lang ch
|
||||
```
|
||||
|
||||
#### 1.2.3 本地构建whl包并安装
|
||||
|
||||
编译与安装新的whl包,其中0.0.0为版本号,可在 `setup.py` 中指定新版本。
|
||||
|
||||
```bash
|
||||
cd ./PPOCRLabel
|
||||
python3 setup.py bdist_wheel
|
||||
pip3 install dist/PPOCRLabel-0.0.0-py2.py3-none-any.whl -i https://mirror.baidu.com/pypi/simple
|
||||
```
|
||||
|
||||
|
||||
## 2. 使用
|
||||
|
||||
### 2.1 操作步骤
|
||||
> 如果您只需要标注文字信息和位置,推荐按照以下步骤展开:
|
||||
|
||||
1. 安装与运行:使用上述命令安装与运行程序。
|
||||
2. 打开文件夹:在菜单栏点击 “文件” - "打开目录" 选择待标记图片的文件夹<sup>[1]</sup>.
|
||||
3. 自动标注:点击 ”自动标注“,使用PP-OCR超轻量模型对图片文件名前图片状态<sup>[2]</sup>为 “X” 的图片进行自动标注。
|
||||
4. 手动标注:点击 “矩形标注”(推荐直接在英文模式下点击键盘中的 “W”),用户可对当前图片中模型未检出的部分进行手动绘制标记框。点击键盘Q,则使用四点标注模式(或点击“编辑” - “四点标注”),用户依次点击4个点后,双击左键表示标注完成。
|
||||
5. 标记框绘制完成后,用户点击 “确认”,检测框会先被预分配一个 “待识别” 标签。
|
||||
6. 重新识别:将图片中的所有检测画绘制/调整完成后,点击 “重新识别”,PP-OCR模型会对当前图片中的**所有检测框**重新识别<sup>[3]</sup>。
|
||||
7. 内容更改:单击识别结果,对不准确的识别结果进行手动更改。
|
||||
8. **确认标记:点击 “确认”,图片状态切换为 “√”,跳转至下一张。**
|
||||
9. 删除:点击 “删除图像”,图片将会被删除至回收站。
|
||||
10. 导出结果:用户可以通过菜单中“文件-导出标记结果”手动导出,同时也可以点击“文件 - 自动导出标记结果”开启自动导出。手动确认过的标记将会被存放在所打开图片文件夹下的*Label.txt*中。在菜单栏点击 “文件” - "导出识别结果"后,会将此类图片的识别训练数据保存在*crop_img*文件夹下,识别标签保存在*rec_gt.txt*中<sup>[4]</sup>。
|
||||
|
||||
### 2.2 表格标注([视频演示](https://www.bilibili.com/video/BV1wR4y1v7JE/?share_source=copy_web&vd_source=cf1f9d24648d49636e3d109c9f9a377d&t=1998))
|
||||
表格标注针对表格的结构化提取,将图片中的表格转换为Excel格式,因此标注时需要配合外部软件打开Excel同时完成。在PPOCRLabel软件中完成表格中的文字信息标注(文字与位置)、在Excel文件中完成表格结构信息标注,推荐的步骤为:
|
||||
1. 表格识别:打开表格图片后,点击软件右上角 `表格识别` 按钮,软件调用PP-Structure中的表格识别模型,自动为表格打标签,同时弹出Excel
|
||||
|
||||
2. 更改标注结果:**以表格中的单元格为单位增加标注框**(即一个单元格内的文字都标记为一个框)。标注框上鼠标右键后点击 `单元格重识别`
|
||||
可利用模型自动识别单元格内的文字。
|
||||
|
||||
> 注意:如果表格中存在空白单元格,同样需要使用一个标注框将其标出,使得单元格总数与图像中保持一致。
|
||||
|
||||
3. **调整单元格顺序**:点击软件`视图-显示框编号` 打开标注框序号,在软件界面右侧拖动 `识别结果` 一栏下的所有结果,使得标注框编号按照从左到右,从上到下的顺序排列,按行依次标注。
|
||||
|
||||
4. 标注表格结构:**在外部Excel软件中,将存在文字的单元格标记为任意标识符(如 `1` )**,保证Excel中的单元格合并情况与原图相同即可(即不需要Excel中的单元格文字与图片中的文字完全相同)
|
||||
|
||||
5. 导出JSON格式:关闭所有表格图像对应的Excel,点击 `文件`-`导出表格标注`,生成gt.txt标注文件。
|
||||
|
||||
### 2.3 注意
|
||||
|
||||
[1] PPOCRLabel以**文件夹**为基本标记单位,打开待标记的图片文件夹后,不会在窗口栏中显示图片,而是在点击 "选择文件夹" 之后直接将文件夹下的图片导入到程序中。
|
||||
|
||||
[2] 图片状态表示本张图片用户是否手动保存过,未手动保存过即为 “X”,手动保存过为 “√”。点击 “自动标注”按钮后,PPOCRLabel不会对状态为 “√” 的图片重新标注。
|
||||
|
||||
[3] 点击“重新识别”后,模型会对图片中的识别结果进行覆盖。因此如果在此之前手动更改过识别结果,有可能在重新识别后产生变动。
|
||||
|
||||
[4] PPOCRLabel产生的文件放置于标记图片文件夹下,包括一下几种,请勿手动更改其中内容,否则会引起程序出现异常。
|
||||
|
||||
| 文件名 | 说明 |
|
||||
| :-----------: | :----------------------------------------------------------: |
|
||||
| Label.txt | 检测标签,可直接用于PPOCR检测模型训练。用户每确认5张检测结果后,程序会进行自动写入。当用户关闭应用程序或切换文件路径后同样会进行写入。 |
|
||||
| fileState.txt | 图片状态标记文件,保存当前文件夹下已经被用户手动确认过的图片名称。 |
|
||||
| Cache.cach | 缓存文件,保存模型自动识别的结果。 |
|
||||
| rec_gt.txt | 识别标签。可直接用于PPOCR识别模型训练。需用户手动点击菜单栏“文件” - "导出识别结果"后产生。 |
|
||||
| crop_img | 识别数据。按照检测框切割后的图片。与rec_gt.txt同时产生。 |
|
||||
|
||||
|
||||
|
||||
## 3. 说明
|
||||
|
||||
### 3.1 快捷键
|
||||
|
||||
| 快捷键 | 说明 |
|
||||
|------------------|---------------------------------|
|
||||
| Ctrl + shift + R | 对当前图片的所有标记重新识别 |
|
||||
| W | 新建矩形框 |
|
||||
| Q | 新建多点框 |
|
||||
| X | 框逆时针旋转 |
|
||||
| C | 框顺时针旋转 |
|
||||
| Ctrl + E | 编辑所选框标签 |
|
||||
| Ctrl + X | `--kie` 模式下,修改 Box 的关键字种类 |
|
||||
| Ctrl + R | 重新识别所选标记 |
|
||||
| Ctrl + C | 【复制并粘贴】选中的标记框 |
|
||||
| Ctrl + 鼠标左键 | 多选标记框 |
|
||||
| Backspace | 删除所选框 |
|
||||
| Ctrl + V | 确认本张图片标记 |
|
||||
| Ctrl + Shift + d | 删除本张图片 |
|
||||
| D | 下一张图片 |
|
||||
| A | 上一张图片 |
|
||||
| Ctrl++ | 缩小 |
|
||||
| Ctrl-- | 放大 |
|
||||
| ↑→↓← | 移动标记框 |
|
||||
|
||||
|
||||
### 3.2 内置模型
|
||||
|
||||
- 默认模型:PPOCRLabel默认使用PaddleOCR中的中英文超轻量OCR模型,支持中英文与数字识别,多种语言检测。
|
||||
|
||||
- 模型语言切换:用户可通过菜单栏中 "PaddleOCR" - "选择模型" 切换内置模型语言,目前支持的语言包括法文、德文、韩文、日文。具体模型下载链接可参考[PaddleOCR模型列表](https://github.com/PaddlePaddle/PaddleOCR/blob/release/2.6/doc/doc_ch/models_list.md).
|
||||
|
||||
- **自定义模型**:如果用户想将内置模型更换为自己的推理模型,可根据[自定义模型代码使用](https://github.com/PaddlePaddle/PaddleOCR/blob/release/2.6/doc/doc_ch/whl.md#3-%E8%87%AA%E5%AE%9A%E4%B9%89%E6%A8%A1%E5%9E%8B),通过修改PPOCRLabel.py中针对[PaddleOCR类的实例化](https://github.com/PaddlePaddle/PaddleOCR/blob/release/2.6/PPOCRLabel/PPOCRLabel.py#L97) 或者[PPStructure](https://github.com/PaddlePaddle/PaddleOCR/blob/release/2.6/PPOCRLabel/PPOCRLabel.py#L104)实现,例如指定检测模型:`self.ocr = PaddleOCR(det=True, cls=True, use_gpu=gpu, lang=lang) `,在 `det_model_dir` 中传入自己的模型即可。
|
||||
|
||||
### 3.3 导出标记结果
|
||||
|
||||
PPOCRLabel支持三种导出方式:
|
||||
|
||||
- 自动导出:点击“文件 - 自动导出标记结果”后,用户每确认过一张图片,程序自动将标记结果写入Label.txt中。若未开启此选项,则检测到用户手动确认过5张图片后进行自动导出。
|
||||
|
||||
> 默认情况下自动导出功能为关闭状态
|
||||
|
||||
- 手动导出:点击“文件 - 导出标记结果”手动导出标记。
|
||||
|
||||
- 关闭应用程序导出
|
||||
|
||||
### 3.4 数据集划分
|
||||
|
||||
在终端中输入以下命令执行数据集划分脚本:
|
||||
|
||||
```
|
||||
cd ./PPOCRLabel # 将目录切换到PPOCRLabel文件夹下
|
||||
python gen_ocr_train_val_test.py --trainValTestRatio 6:2:2 --datasetRootPath ../train_data
|
||||
```
|
||||
|
||||
参数说明:
|
||||
|
||||
- `trainValTestRatio` 是训练集、验证集、测试集的图像数量划分比例,根据实际情况设定,默认是`6:2:2`
|
||||
|
||||
- `datasetRootPath` 是PPOCRLabel标注的完整数据集存放路径。默认路径是 `PaddleOCR/train_data` 分割数据集前应有如下结构:
|
||||
```
|
||||
|-train_data
|
||||
|-crop_img
|
||||
|- word_001_crop_0.png
|
||||
|- word_002_crop_0.jpg
|
||||
|- word_003_crop_0.jpg
|
||||
| ...
|
||||
| Label.txt
|
||||
| rec_gt.txt
|
||||
|- word_001.png
|
||||
|- word_002.jpg
|
||||
|- word_003.jpg
|
||||
| ...
|
||||
```
|
||||
|
||||
### 3.5 错误提示
|
||||
|
||||
- 如果同时使用whl包安装了paddleocr,其优先级大于通过paddleocr.py调用PaddleOCR类,whl包未更新时会导致程序异常。
|
||||
|
||||
- PPOCRLabel**不支持对中文文件名**的图片进行自动标注。
|
||||
|
||||
- 针对Linux用户:如果您在打开软件过程中出现**objc[XXXXX]**开头的错误,证明您的opencv版本太高,建议安装4.2版本:
|
||||
```
|
||||
pip install opencv-python==4.2.0.32
|
||||
```
|
||||
|
||||
- 如果出现 ```Missing string id``` 开头的错误,需要重新编译资源:
|
||||
```
|
||||
pyrcc5 -o libs/resources.py resources.qrc
|
||||
```
|
||||
|
||||
- 如果出现``` module 'cv2' has no attribute 'INTER_NEAREST'```错误,需要首先删除所有opencv相关包,然后重新安装4.2.0.32版本的headless opencv
|
||||
```
|
||||
pip install opencv-contrib-python-headless==4.2.0.32
|
||||
```
|
||||
|
||||
|
||||
|
||||
### 4. 参考资料
|
||||
|
||||
1.[Tzutalin. LabelImg. Git code (2015)](https://github.com/tzutalin/labelImg)
|
Before Width: | Height: | Size: 5.6 MiB |
Before Width: | Height: | Size: 818 KiB |
Before Width: | Height: | Size: 4.8 MiB |
Before Width: | Height: | Size: 1.9 MiB |
Before Width: | Height: | Size: 6.4 KiB |
|
@ -1,178 +0,0 @@
|
|||
# coding:utf8
|
||||
import os
|
||||
import shutil
|
||||
import random
|
||||
import argparse
|
||||
|
||||
|
||||
# 删除划分的训练集、验证集、测试集文件夹,重新创建一个空的文件夹
|
||||
def isCreateOrDeleteFolder(path, flag):
|
||||
flagPath = os.path.join(path, flag)
|
||||
|
||||
if os.path.exists(flagPath):
|
||||
shutil.rmtree(flagPath)
|
||||
|
||||
os.makedirs(flagPath)
|
||||
flagAbsPath = os.path.abspath(flagPath)
|
||||
return flagAbsPath
|
||||
|
||||
|
||||
def splitTrainVal(
|
||||
root,
|
||||
abs_train_root_path,
|
||||
abs_val_root_path,
|
||||
abs_test_root_path,
|
||||
train_txt,
|
||||
val_txt,
|
||||
test_txt,
|
||||
flag,
|
||||
):
|
||||
data_abs_path = os.path.abspath(root)
|
||||
label_file_name = args.detLabelFileName if flag == "det" else args.recLabelFileName
|
||||
label_file_path = os.path.join(data_abs_path, label_file_name)
|
||||
|
||||
with open(label_file_path, "r", encoding="UTF-8") as label_file:
|
||||
label_file_content = label_file.readlines()
|
||||
random.shuffle(label_file_content)
|
||||
label_record_len = len(label_file_content)
|
||||
|
||||
for index, label_record_info in enumerate(label_file_content):
|
||||
image_relative_path, image_label = label_record_info.split("\t")
|
||||
image_name = os.path.basename(image_relative_path)
|
||||
|
||||
if flag == "det":
|
||||
image_path = os.path.join(data_abs_path, image_name)
|
||||
elif flag == "rec":
|
||||
image_path = os.path.join(
|
||||
data_abs_path, args.recImageDirName, image_name
|
||||
)
|
||||
|
||||
train_val_test_ratio = args.trainValTestRatio.split(":")
|
||||
train_ratio = eval(train_val_test_ratio[0]) / 10
|
||||
val_ratio = train_ratio + eval(train_val_test_ratio[1]) / 10
|
||||
cur_ratio = index / label_record_len
|
||||
|
||||
if cur_ratio < train_ratio:
|
||||
image_copy_path = os.path.join(abs_train_root_path, image_name)
|
||||
shutil.copy(image_path, image_copy_path)
|
||||
train_txt.write("{}\t{}".format(image_copy_path, image_label))
|
||||
elif cur_ratio >= train_ratio and cur_ratio < val_ratio:
|
||||
image_copy_path = os.path.join(abs_val_root_path, image_name)
|
||||
shutil.copy(image_path, image_copy_path)
|
||||
val_txt.write("{}\t{}".format(image_copy_path, image_label))
|
||||
else:
|
||||
image_copy_path = os.path.join(abs_test_root_path, image_name)
|
||||
shutil.copy(image_path, image_copy_path)
|
||||
test_txt.write("{}\t{}".format(image_copy_path, image_label))
|
||||
|
||||
|
||||
# 删掉存在的文件
|
||||
def removeFile(path):
|
||||
if os.path.exists(path):
|
||||
os.remove(path)
|
||||
|
||||
|
||||
def genDetRecTrainVal(args):
|
||||
detAbsTrainRootPath = isCreateOrDeleteFolder(args.detRootPath, "train")
|
||||
detAbsValRootPath = isCreateOrDeleteFolder(args.detRootPath, "val")
|
||||
detAbsTestRootPath = isCreateOrDeleteFolder(args.detRootPath, "test")
|
||||
recAbsTrainRootPath = isCreateOrDeleteFolder(args.recRootPath, "train")
|
||||
recAbsValRootPath = isCreateOrDeleteFolder(args.recRootPath, "val")
|
||||
recAbsTestRootPath = isCreateOrDeleteFolder(args.recRootPath, "test")
|
||||
|
||||
removeFile(os.path.join(args.detRootPath, "train.txt"))
|
||||
removeFile(os.path.join(args.detRootPath, "val.txt"))
|
||||
removeFile(os.path.join(args.detRootPath, "test.txt"))
|
||||
removeFile(os.path.join(args.recRootPath, "train.txt"))
|
||||
removeFile(os.path.join(args.recRootPath, "val.txt"))
|
||||
removeFile(os.path.join(args.recRootPath, "test.txt"))
|
||||
|
||||
detTrainTxt = open(
|
||||
os.path.join(args.detRootPath, "train.txt"), "a", encoding="UTF-8"
|
||||
)
|
||||
detValTxt = open(os.path.join(args.detRootPath, "val.txt"), "a", encoding="UTF-8")
|
||||
detTestTxt = open(os.path.join(args.detRootPath, "test.txt"), "a", encoding="UTF-8")
|
||||
recTrainTxt = open(
|
||||
os.path.join(args.recRootPath, "train.txt"), "a", encoding="UTF-8"
|
||||
)
|
||||
recValTxt = open(os.path.join(args.recRootPath, "val.txt"), "a", encoding="UTF-8")
|
||||
recTestTxt = open(os.path.join(args.recRootPath, "test.txt"), "a", encoding="UTF-8")
|
||||
|
||||
splitTrainVal(
|
||||
args.datasetRootPath,
|
||||
detAbsTrainRootPath,
|
||||
detAbsValRootPath,
|
||||
detAbsTestRootPath,
|
||||
detTrainTxt,
|
||||
detValTxt,
|
||||
detTestTxt,
|
||||
"det",
|
||||
)
|
||||
|
||||
for root, dirs, files in os.walk(args.datasetRootPath):
|
||||
for dir in dirs:
|
||||
if dir == "crop_img":
|
||||
splitTrainVal(
|
||||
root,
|
||||
recAbsTrainRootPath,
|
||||
recAbsValRootPath,
|
||||
recAbsTestRootPath,
|
||||
recTrainTxt,
|
||||
recValTxt,
|
||||
recTestTxt,
|
||||
"rec",
|
||||
)
|
||||
else:
|
||||
continue
|
||||
break
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# 功能描述:分别划分检测和识别的训练集、验证集、测试集
|
||||
# 说明:可以根据自己的路径和需求调整参数,图像数据往往多人合作分批标注,每一批图像数据放在一个文件夹内用PPOCRLabel进行标注,
|
||||
# 如此会有多个标注好的图像文件夹汇总并划分训练集、验证集、测试集的需求
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument(
|
||||
"--trainValTestRatio",
|
||||
type=str,
|
||||
default="6:2:2",
|
||||
help="ratio of trainset:valset:testset",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--datasetRootPath",
|
||||
type=str,
|
||||
default="../train_data/",
|
||||
help="path to the dataset marked by ppocrlabel, E.g, dataset folder named 1,2,3...",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--detRootPath",
|
||||
type=str,
|
||||
default="../train_data/det",
|
||||
help="the path where the divided detection dataset is placed",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--recRootPath",
|
||||
type=str,
|
||||
default="../train_data/rec",
|
||||
help="the path where the divided recognition dataset is placed",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--detLabelFileName",
|
||||
type=str,
|
||||
default="Label.txt",
|
||||
help="the name of the detection annotation file",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--recLabelFileName",
|
||||
type=str,
|
||||
default="rec_gt.txt",
|
||||
help="the name of the recognition annotation file",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--recImageDirName",
|
||||
type=str,
|
||||
default="crop_img",
|
||||
help="the name of the folder where the cropped recognition dataset is located",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
genDetRecTrainVal(args)
|
|
@ -1,2 +0,0 @@
|
|||
__version_info__ = ("1", "0", "0")
|
||||
__version__ = ".".join(__version_info__)
|
|
@ -1,191 +0,0 @@
|
|||
try:
|
||||
from PyQt5.QtGui import *
|
||||
from PyQt5.QtCore import *
|
||||
from PyQt5.QtWidgets import *
|
||||
except ImportError:
|
||||
from PyQt4.QtGui import *
|
||||
from PyQt4.QtCore import *
|
||||
|
||||
import time
|
||||
import datetime
|
||||
import json
|
||||
import cv2
|
||||
import numpy as np
|
||||
|
||||
from libs.utils import newIcon
|
||||
|
||||
BB = QDialogButtonBox
|
||||
|
||||
|
||||
class Worker(QThread):
|
||||
progressBarValue = pyqtSignal(int)
|
||||
listValue = pyqtSignal(str)
|
||||
endsignal = pyqtSignal(int, str)
|
||||
handle = 0
|
||||
|
||||
def __init__(self, ocr, mImgList, mainThread, model):
|
||||
super(Worker, self).__init__()
|
||||
self.ocr = ocr
|
||||
self.mImgList = mImgList
|
||||
self.mainThread = mainThread
|
||||
self.model = model
|
||||
self.setStackSize(1024 * 1024)
|
||||
|
||||
def run(self):
|
||||
try:
|
||||
findex = 0
|
||||
for Imgpath in self.mImgList:
|
||||
if self.handle == 0:
|
||||
self.listValue.emit(Imgpath)
|
||||
if self.model == "paddle":
|
||||
h, w, _ = cv2.imdecode(
|
||||
np.fromfile(Imgpath, dtype=np.uint8), 1
|
||||
).shape
|
||||
if h > 32 and w > 32:
|
||||
self.result_dic = self.ocr.ocr(Imgpath, cls=True, det=True)[
|
||||
0
|
||||
]
|
||||
else:
|
||||
print(
|
||||
"The size of", Imgpath, "is too small to be recognised"
|
||||
)
|
||||
self.result_dic = None
|
||||
|
||||
# 结果保存
|
||||
if self.result_dic is None or len(self.result_dic) == 0:
|
||||
print("Can not recognise file", Imgpath)
|
||||
pass
|
||||
else:
|
||||
strs = ""
|
||||
for res in self.result_dic:
|
||||
chars = res[1][0]
|
||||
cond = res[1][1]
|
||||
posi = res[0]
|
||||
strs += (
|
||||
"Transcription: "
|
||||
+ chars
|
||||
+ " Probability: "
|
||||
+ str(cond)
|
||||
+ " Location: "
|
||||
+ json.dumps(posi)
|
||||
+ "\n"
|
||||
)
|
||||
# Sending large amounts of data repeatedly through pyqtSignal may affect the program efficiency
|
||||
self.listValue.emit(strs)
|
||||
self.mainThread.result_dic = self.result_dic
|
||||
self.mainThread.filePath = Imgpath
|
||||
# 保存
|
||||
self.mainThread.saveFile(mode="Auto")
|
||||
findex += 1
|
||||
self.progressBarValue.emit(findex)
|
||||
else:
|
||||
break
|
||||
self.endsignal.emit(0, "readAll")
|
||||
self.exec()
|
||||
except Exception as e:
|
||||
print(e)
|
||||
raise
|
||||
|
||||
|
||||
class AutoDialog(QDialog):
|
||||
def __init__(
|
||||
self, text="Enter object label", parent=None, ocr=None, mImgList=None, lenbar=0
|
||||
):
|
||||
super(AutoDialog, self).__init__(parent)
|
||||
self.setFixedWidth(1000)
|
||||
self.parent = parent
|
||||
self.ocr = ocr
|
||||
self.mImgList = mImgList
|
||||
self.lender = lenbar
|
||||
self.pb = QProgressBar()
|
||||
self.pb.setRange(0, self.lender)
|
||||
self.pb.setValue(0)
|
||||
|
||||
layout = QVBoxLayout()
|
||||
layout.addWidget(self.pb)
|
||||
self.model = "paddle"
|
||||
self.listWidget = QListWidget(self)
|
||||
layout.addWidget(self.listWidget)
|
||||
|
||||
self.buttonBox = bb = BB(BB.Ok | BB.Cancel, Qt.Horizontal, self)
|
||||
bb.button(BB.Ok).setIcon(newIcon("done"))
|
||||
bb.button(BB.Cancel).setIcon(newIcon("undo"))
|
||||
bb.accepted.connect(self.validate)
|
||||
bb.rejected.connect(self.reject)
|
||||
layout.addWidget(bb)
|
||||
bb.button(BB.Ok).setEnabled(False)
|
||||
|
||||
self.setLayout(layout)
|
||||
# self.setWindowTitle("自动标注中")
|
||||
self.setWindowModality(Qt.ApplicationModal)
|
||||
|
||||
# self.setWindowFlags(Qt.WindowCloseButtonHint)
|
||||
|
||||
self.thread_1 = Worker(self.ocr, self.mImgList, self.parent, "paddle")
|
||||
self.thread_1.progressBarValue.connect(self.handleProgressBarSingal)
|
||||
self.thread_1.listValue.connect(self.handleListWidgetSingal)
|
||||
self.thread_1.endsignal.connect(self.handleEndsignalSignal)
|
||||
self.time_start = time.time() # save start time
|
||||
|
||||
def handleProgressBarSingal(self, i):
|
||||
self.pb.setValue(i)
|
||||
|
||||
# calculate time left of auto labeling
|
||||
avg_time = (
|
||||
time.time() - self.time_start
|
||||
) / i # Use average time to prevent time fluctuations
|
||||
time_left = str(datetime.timedelta(seconds=avg_time * (self.lender - i))).split(
|
||||
"."
|
||||
)[
|
||||
0
|
||||
] # Remove microseconds
|
||||
self.setWindowTitle("PPOCRLabel -- " + f"Time Left: {time_left}") # show
|
||||
|
||||
def handleListWidgetSingal(self, i):
|
||||
self.listWidget.addItem(i)
|
||||
titem = self.listWidget.item(self.listWidget.count() - 1)
|
||||
self.listWidget.scrollToItem(titem)
|
||||
|
||||
def handleEndsignalSignal(self, i, str):
|
||||
if i == 0 and str == "readAll":
|
||||
self.buttonBox.button(BB.Ok).setEnabled(True)
|
||||
self.buttonBox.button(BB.Cancel).setEnabled(False)
|
||||
|
||||
def reject(self):
|
||||
print("reject")
|
||||
self.thread_1.handle = -1
|
||||
self.thread_1.quit()
|
||||
# del self.thread_1
|
||||
# if self.thread_1.isRunning():
|
||||
# self.thread_1.terminate()
|
||||
# self.thread_1.quit()
|
||||
# super(AutoDialog,self).reject()
|
||||
while not self.thread_1.isFinished():
|
||||
pass
|
||||
self.accept()
|
||||
|
||||
def validate(self):
|
||||
self.accept()
|
||||
|
||||
def postProcess(self):
|
||||
try:
|
||||
self.edit.setText(self.edit.text().trimmed())
|
||||
# print(self.edit.text())
|
||||
except AttributeError:
|
||||
# PyQt5: AttributeError: 'str' object has no attribute 'trimmed'
|
||||
self.edit.setText(self.edit.text())
|
||||
print(self.edit.text())
|
||||
|
||||
def popUp(self):
|
||||
self.thread_1.start()
|
||||
return 1 if self.exec_() else None
|
||||
|
||||
def closeEvent(self, event):
|
||||
print("???")
|
||||
# if self.thread_1.isRunning():
|
||||
# self.thread_1.quit()
|
||||
#
|
||||
# # self._thread.terminate()
|
||||
# # del self.thread_1
|
||||
# super(AutoDialog, self).closeEvent(event)
|
||||
self.reject()
|
|
@ -1,936 +0,0 @@
|
|||
# Copyright (c) <2015-Present> Tzutalin
|
||||
# Copyright (C) 2013 MIT, Computer Science and Artificial Intelligence Laboratory. Bryan Russell, Antonio Torralba,
|
||||
# William T. Freeman. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
# associated documentation files (the "Software"), to deal in the Software without restriction, including without
|
||||
# limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
# Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of
|
||||
# the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
# NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
||||
# SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
import copy
|
||||
|
||||
from PyQt5.QtCore import Qt, pyqtSignal, QPointF, QPoint
|
||||
from PyQt5.QtGui import QPainter, QBrush, QColor, QPixmap
|
||||
from PyQt5.QtWidgets import QWidget, QMenu, QApplication
|
||||
from libs.shape import Shape
|
||||
from libs.utils import distance
|
||||
|
||||
CURSOR_DEFAULT = Qt.ArrowCursor
|
||||
CURSOR_POINT = Qt.PointingHandCursor
|
||||
CURSOR_DRAW = Qt.CrossCursor
|
||||
CURSOR_MOVE = Qt.ClosedHandCursor
|
||||
CURSOR_GRAB = Qt.OpenHandCursor
|
||||
|
||||
|
||||
class Canvas(QWidget):
|
||||
zoomRequest = pyqtSignal(int)
|
||||
scrollRequest = pyqtSignal(int, int)
|
||||
newShape = pyqtSignal()
|
||||
# selectionChanged = pyqtSignal(bool)
|
||||
selectionChanged = pyqtSignal(list)
|
||||
shapeMoved = pyqtSignal()
|
||||
drawingPolygon = pyqtSignal(bool)
|
||||
|
||||
CREATE, EDIT = list(range(2))
|
||||
_fill_drawing = False # draw shadows
|
||||
|
||||
epsilon = 5.0
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(Canvas, self).__init__(*args, **kwargs)
|
||||
# Initialise local state.
|
||||
self.mode = self.EDIT
|
||||
self.shapes = []
|
||||
self.shapesBackups = []
|
||||
self.current = None
|
||||
self.selectedShapes = []
|
||||
self.selectedShape = None # save the selected shape here
|
||||
self.selectedShapesCopy = []
|
||||
self.drawingLineColor = QColor(0, 0, 255)
|
||||
self.drawingRectColor = QColor(0, 0, 255)
|
||||
self.line = Shape(line_color=self.drawingLineColor)
|
||||
self.prevPoint = QPointF()
|
||||
self.offsets = QPointF(), QPointF()
|
||||
self.scale = 1.0
|
||||
self.pixmap = QPixmap()
|
||||
self.visible = {}
|
||||
self._hideBackround = False
|
||||
self.hideBackround = False
|
||||
self.hShape = None
|
||||
self.hVertex = None
|
||||
self._painter = QPainter()
|
||||
self._cursor = CURSOR_DEFAULT
|
||||
# Menus:
|
||||
self.menus = (QMenu(), QMenu())
|
||||
# Set widget options.
|
||||
self.setMouseTracking(True)
|
||||
self.setFocusPolicy(Qt.WheelFocus)
|
||||
self.verified = False
|
||||
self.drawSquare = False
|
||||
self.fourpoint = True # ADD
|
||||
self.pointnum = 0
|
||||
self.movingShape = False
|
||||
self.selectCountShape = False
|
||||
|
||||
# initialisation for panning
|
||||
self.pan_initial_pos = QPoint()
|
||||
|
||||
# lockedshapes related
|
||||
self.lockedShapes = []
|
||||
self.isInTheSameImage = False
|
||||
|
||||
def setDrawingColor(self, qColor):
|
||||
self.drawingLineColor = qColor
|
||||
self.drawingRectColor = qColor
|
||||
|
||||
def enterEvent(self, ev):
|
||||
self.overrideCursor(self._cursor)
|
||||
|
||||
def leaveEvent(self, ev):
|
||||
self.restoreCursor()
|
||||
|
||||
def focusOutEvent(self, ev):
|
||||
self.restoreCursor()
|
||||
|
||||
def isVisible(self, shape):
|
||||
return self.visible.get(shape, True)
|
||||
|
||||
def drawing(self):
|
||||
return self.mode == self.CREATE
|
||||
|
||||
def editing(self):
|
||||
return self.mode == self.EDIT
|
||||
|
||||
def setEditing(self, value=True):
|
||||
self.mode = self.EDIT if value else self.CREATE
|
||||
if not value: # Create
|
||||
self.unHighlight()
|
||||
self.deSelectShape()
|
||||
self.prevPoint = QPointF()
|
||||
self.repaint()
|
||||
|
||||
def unHighlight(self):
|
||||
if self.hShape:
|
||||
self.hShape.highlightClear()
|
||||
self.hVertex = self.hShape = None
|
||||
|
||||
def selectedVertex(self):
|
||||
return self.hVertex is not None
|
||||
|
||||
def mouseMoveEvent(self, ev):
|
||||
"""Update line with last point and current coordinates."""
|
||||
pos = self.transformPos(ev.pos())
|
||||
|
||||
# Update coordinates in status bar if image is opened
|
||||
window = self.parent().window()
|
||||
if window.filePath is not None:
|
||||
self.parent().window().labelCoordinates.setText(
|
||||
"X: %d; Y: %d" % (pos.x(), pos.y())
|
||||
)
|
||||
|
||||
# Polygon drawing.
|
||||
if self.drawing():
|
||||
self.overrideCursor(CURSOR_DRAW) # ?
|
||||
if self.current:
|
||||
# Display annotation width and height while drawing
|
||||
currentWidth = abs(self.current[0].x() - pos.x())
|
||||
currentHeight = abs(self.current[0].y() - pos.y())
|
||||
self.parent().window().labelCoordinates.setText(
|
||||
"Width: %d, Height: %d / X: %d; Y: %d"
|
||||
% (currentWidth, currentHeight, pos.x(), pos.y())
|
||||
)
|
||||
|
||||
color = self.drawingLineColor
|
||||
if self.outOfPixmap(pos):
|
||||
# Don't allow the user to draw outside the pixmap.
|
||||
# Clip the coordinates to 0 or max,
|
||||
# if they are outside the range [0, max]
|
||||
size = self.pixmap.size()
|
||||
clipped_x = min(max(0, pos.x()), size.width())
|
||||
clipped_y = min(max(0, pos.y()), size.height())
|
||||
pos = QPointF(clipped_x, clipped_y)
|
||||
|
||||
elif len(self.current) > 1 and self.closeEnough(pos, self.current[0]):
|
||||
# Attract line to starting point and colorise to alert the
|
||||
# user:
|
||||
pos = self.current[0]
|
||||
color = self.current.line_color
|
||||
self.overrideCursor(CURSOR_POINT)
|
||||
self.current.highlightVertex(0, Shape.NEAR_VERTEX)
|
||||
|
||||
if self.drawSquare:
|
||||
self.line.points = [self.current[0], pos]
|
||||
self.line.close()
|
||||
|
||||
elif self.fourpoint:
|
||||
self.line[0] = self.current[-1]
|
||||
self.line[1] = pos
|
||||
|
||||
else:
|
||||
self.line[1] = pos # pos is the mouse's current position
|
||||
|
||||
self.line.line_color = color
|
||||
self.prevPoint = QPointF() # ?
|
||||
self.current.highlightClear()
|
||||
else:
|
||||
self.prevPoint = pos
|
||||
self.repaint()
|
||||
return
|
||||
|
||||
# Polygon copy moving.
|
||||
if Qt.RightButton & ev.buttons():
|
||||
if self.selectedShapesCopy and self.prevPoint:
|
||||
self.overrideCursor(CURSOR_MOVE)
|
||||
self.boundedMoveShape(self.selectedShapesCopy, pos)
|
||||
self.repaint()
|
||||
elif self.selectedShapes:
|
||||
self.selectedShapesCopy = [s.copy() for s in self.selectedShapes]
|
||||
self.repaint()
|
||||
return
|
||||
|
||||
# Polygon/Vertex moving.
|
||||
if Qt.LeftButton & ev.buttons():
|
||||
if self.selectedVertex():
|
||||
self.boundedMoveVertex(pos)
|
||||
self.shapeMoved.emit()
|
||||
self.repaint()
|
||||
self.movingShape = True
|
||||
elif self.selectedShapes and self.prevPoint:
|
||||
self.overrideCursor(CURSOR_MOVE)
|
||||
self.boundedMoveShape(self.selectedShapes, pos)
|
||||
self.shapeMoved.emit()
|
||||
self.repaint()
|
||||
self.movingShape = True
|
||||
else:
|
||||
# pan
|
||||
delta_x = pos.x() - self.pan_initial_pos.x()
|
||||
delta_y = pos.y() - self.pan_initial_pos.y()
|
||||
self.scrollRequest.emit(delta_x, Qt.Horizontal)
|
||||
self.scrollRequest.emit(delta_y, Qt.Vertical)
|
||||
self.update()
|
||||
return
|
||||
|
||||
# Just hovering over the canvas, 2 posibilities:
|
||||
# - Highlight shapes
|
||||
# - Highlight vertex
|
||||
# Update shape/vertex fill and tooltip value accordingly.
|
||||
self.setToolTip("Image")
|
||||
for shape in reversed([s for s in self.shapes if self.isVisible(s)]):
|
||||
# Look for a nearby vertex to highlight. If that fails,
|
||||
# check if we happen to be inside a shape.
|
||||
index = shape.nearestVertex(pos, self.epsilon)
|
||||
if index is not None:
|
||||
if self.selectedVertex():
|
||||
self.hShape.highlightClear()
|
||||
self.hVertex, self.hShape = index, shape
|
||||
shape.highlightVertex(index, shape.MOVE_VERTEX)
|
||||
self.overrideCursor(CURSOR_POINT)
|
||||
self.setToolTip("Click & drag to move point")
|
||||
self.setStatusTip(self.toolTip())
|
||||
self.update()
|
||||
break
|
||||
else:
|
||||
for shape in reversed([s for s in self.shapes if self.isVisible(s)]):
|
||||
if shape.containsPoint(pos):
|
||||
if self.selectedVertex():
|
||||
self.hShape.highlightClear()
|
||||
self.hVertex, self.hShape = None, shape
|
||||
self.setToolTip("Click & drag to move shape '%s'" % shape.label)
|
||||
self.setStatusTip(self.toolTip())
|
||||
self.overrideCursor(CURSOR_GRAB)
|
||||
self.update()
|
||||
break
|
||||
else: # Nothing found, clear highlights, reset state.
|
||||
if self.hShape:
|
||||
self.hShape.highlightClear()
|
||||
self.update()
|
||||
self.hVertex, self.hShape = None, None
|
||||
self.overrideCursor(CURSOR_DEFAULT)
|
||||
|
||||
def mousePressEvent(self, ev):
|
||||
pos = self.transformPos(ev.pos())
|
||||
if ev.button() == Qt.LeftButton:
|
||||
if self.drawing():
|
||||
# self.handleDrawing(pos) # OLD
|
||||
if self.current:
|
||||
if self.fourpoint: # ADD IF
|
||||
# Add point to existing shape.
|
||||
# print('Adding points in mousePressEvent is ', self.line[1])
|
||||
self.current.addPoint(self.line[1])
|
||||
self.line[0] = self.current[-1]
|
||||
if self.current.isClosed():
|
||||
# print('1111')
|
||||
self.finalise()
|
||||
elif self.drawSquare:
|
||||
assert len(self.current.points) == 1
|
||||
self.current.points = self.line.points
|
||||
self.finalise()
|
||||
elif not self.outOfPixmap(pos):
|
||||
# Create new shape.
|
||||
self.current = Shape()
|
||||
self.current.addPoint(pos)
|
||||
self.line.points = [pos, pos]
|
||||
self.setHiding()
|
||||
self.drawingPolygon.emit(True)
|
||||
self.update()
|
||||
|
||||
else:
|
||||
group_mode = int(ev.modifiers()) == Qt.ControlModifier
|
||||
self.selectShapePoint(pos, multiple_selection_mode=group_mode)
|
||||
self.prevPoint = pos
|
||||
self.pan_initial_pos = pos
|
||||
|
||||
elif ev.button() == Qt.RightButton and self.editing():
|
||||
group_mode = int(ev.modifiers()) == Qt.ControlModifier
|
||||
self.selectShapePoint(pos, multiple_selection_mode=group_mode)
|
||||
self.prevPoint = pos
|
||||
self.update()
|
||||
|
||||
def mouseReleaseEvent(self, ev):
|
||||
if ev.button() == Qt.RightButton:
|
||||
menu = self.menus[bool(self.selectedShapesCopy)]
|
||||
self.restoreCursor()
|
||||
if not menu.exec_(self.mapToGlobal(ev.pos())) and self.selectedShapesCopy:
|
||||
# Cancel the move by deleting the shadow copy.
|
||||
# self.selectedShapeCopy = None
|
||||
self.selectedShapesCopy = []
|
||||
self.repaint()
|
||||
|
||||
elif ev.button() == Qt.LeftButton and self.selectedShapes:
|
||||
if self.selectedVertex():
|
||||
self.overrideCursor(CURSOR_POINT)
|
||||
else:
|
||||
self.overrideCursor(CURSOR_GRAB)
|
||||
|
||||
elif ev.button() == Qt.LeftButton and not self.fourpoint:
|
||||
pos = self.transformPos(ev.pos())
|
||||
if self.drawing():
|
||||
self.handleDrawing(pos)
|
||||
else:
|
||||
# pan
|
||||
QApplication.restoreOverrideCursor() # ?
|
||||
|
||||
if self.movingShape and self.hShape:
|
||||
if self.hShape in self.shapes:
|
||||
index = self.shapes.index(self.hShape)
|
||||
if self.shapesBackups[-1][index].points != self.shapes[index].points:
|
||||
self.storeShapes()
|
||||
self.shapeMoved.emit() # connect to updateBoxlist in PPOCRLabel.py
|
||||
|
||||
self.movingShape = False
|
||||
|
||||
def endMove(self, copy=False):
|
||||
assert self.selectedShapes and self.selectedShapesCopy
|
||||
assert len(self.selectedShapesCopy) == len(self.selectedShapes)
|
||||
if copy:
|
||||
for i, shape in enumerate(self.selectedShapesCopy):
|
||||
shape.idx = len(self.shapes) # add current box index
|
||||
self.shapes.append(shape)
|
||||
self.selectedShapes[i].selected = False
|
||||
self.selectedShapes[i] = shape
|
||||
else:
|
||||
for i, shape in enumerate(self.selectedShapesCopy):
|
||||
self.selectedShapes[i].points = shape.points
|
||||
self.selectedShapesCopy = []
|
||||
self.repaint()
|
||||
self.storeShapes()
|
||||
return True
|
||||
|
||||
def hideBackroundShapes(self, value):
|
||||
self.hideBackround = value
|
||||
if self.selectedShapes:
|
||||
# Only hide other shapes if there is a current selection.
|
||||
# Otherwise the user will not be able to select a shape.
|
||||
self.setHiding(True)
|
||||
self.repaint()
|
||||
|
||||
def handleDrawing(self, pos):
|
||||
if self.current and self.current.reachMaxPoints() is False:
|
||||
if self.fourpoint:
|
||||
targetPos = self.line[self.pointnum]
|
||||
self.current.addPoint(targetPos)
|
||||
print("current points in handleDrawing is ", self.line[self.pointnum])
|
||||
self.update()
|
||||
if self.pointnum == 3:
|
||||
self.finalise()
|
||||
|
||||
else:
|
||||
initPos = self.current[0]
|
||||
print("initPos", self.current[0])
|
||||
minX = initPos.x()
|
||||
minY = initPos.y()
|
||||
targetPos = self.line[1]
|
||||
maxX = targetPos.x()
|
||||
maxY = targetPos.y()
|
||||
self.current.addPoint(QPointF(maxX, minY))
|
||||
self.current.addPoint(targetPos)
|
||||
self.current.addPoint(QPointF(minX, maxY))
|
||||
self.finalise()
|
||||
|
||||
elif not self.outOfPixmap(pos):
|
||||
print("release")
|
||||
self.current = Shape()
|
||||
self.current.addPoint(pos)
|
||||
self.line.points = [pos, pos]
|
||||
self.setHiding()
|
||||
self.drawingPolygon.emit(True)
|
||||
self.update()
|
||||
|
||||
def setHiding(self, enable=True):
|
||||
self._hideBackround = self.hideBackround if enable else False
|
||||
|
||||
def canCloseShape(self):
|
||||
return self.drawing() and self.current and len(self.current) > 2
|
||||
|
||||
def mouseDoubleClickEvent(self, ev):
|
||||
# We need at least 4 points here, since the mousePress handler
|
||||
# adds an extra one before this handler is called.
|
||||
if self.canCloseShape() and len(self.current) > 3:
|
||||
if not self.fourpoint:
|
||||
self.current.popPoint()
|
||||
self.finalise()
|
||||
|
||||
def selectShapes(self, shapes):
|
||||
for s in shapes:
|
||||
s.seleted = True
|
||||
self.setHiding()
|
||||
self.selectionChanged.emit(shapes)
|
||||
self.update()
|
||||
|
||||
def selectShapePoint(self, point, multiple_selection_mode):
|
||||
"""Select the first shape created which contains this point."""
|
||||
if self.selectedVertex(): # A vertex is marked for selection.
|
||||
index, shape = self.hVertex, self.hShape
|
||||
shape.highlightVertex(index, shape.MOVE_VERTEX)
|
||||
return self.hVertex
|
||||
else:
|
||||
for shape in reversed(self.shapes):
|
||||
if self.isVisible(shape) and shape.containsPoint(point):
|
||||
self.calculateOffsets(shape, point)
|
||||
self.setHiding()
|
||||
if multiple_selection_mode:
|
||||
if shape not in self.selectedShapes: # list
|
||||
self.selectionChanged.emit(self.selectedShapes + [shape])
|
||||
else:
|
||||
self.selectionChanged.emit([shape])
|
||||
return
|
||||
self.deSelectShape()
|
||||
|
||||
def calculateOffsets(self, shape, point):
|
||||
rect = shape.boundingRect()
|
||||
x1 = rect.x() - point.x()
|
||||
y1 = rect.y() - point.y()
|
||||
x2 = (rect.x() + rect.width()) - point.x()
|
||||
y2 = (rect.y() + rect.height()) - point.y()
|
||||
self.offsets = QPointF(x1, y1), QPointF(x2, y2)
|
||||
|
||||
def snapPointToCanvas(self, x, y):
|
||||
"""
|
||||
Moves a point x,y to within the boundaries of the canvas.
|
||||
:return: (x,y,snapped) where snapped is True if x or y were changed, False if not.
|
||||
"""
|
||||
if x < 0 or x > self.pixmap.width() or y < 0 or y > self.pixmap.height():
|
||||
x = max(x, 0)
|
||||
y = max(y, 0)
|
||||
x = min(x, self.pixmap.width())
|
||||
y = min(y, self.pixmap.height())
|
||||
return x, y, True
|
||||
|
||||
return x, y, False
|
||||
|
||||
def boundedMoveVertex(self, pos):
|
||||
index, shape = self.hVertex, self.hShape
|
||||
point = shape[index]
|
||||
if self.outOfPixmap(pos):
|
||||
size = self.pixmap.size()
|
||||
clipped_x = min(max(0, pos.x()), size.width())
|
||||
clipped_y = min(max(0, pos.y()), size.height())
|
||||
pos = QPointF(clipped_x, clipped_y)
|
||||
|
||||
if self.drawSquare:
|
||||
opposite_point_index = (index + 2) % 4
|
||||
opposite_point = shape[opposite_point_index]
|
||||
|
||||
min_size = min(
|
||||
abs(pos.x() - opposite_point.x()), abs(pos.y() - opposite_point.y())
|
||||
)
|
||||
directionX = -1 if pos.x() - opposite_point.x() < 0 else 1
|
||||
directionY = -1 if pos.y() - opposite_point.y() < 0 else 1
|
||||
shiftPos = QPointF(
|
||||
opposite_point.x() + directionX * min_size - point.x(),
|
||||
opposite_point.y() + directionY * min_size - point.y(),
|
||||
)
|
||||
else:
|
||||
shiftPos = pos - point
|
||||
|
||||
if [shape[0].x(), shape[0].y(), shape[2].x(), shape[2].y()] == [
|
||||
shape[3].x(),
|
||||
shape[1].y(),
|
||||
shape[1].x(),
|
||||
shape[3].y(),
|
||||
]:
|
||||
shape.moveVertexBy(index, shiftPos)
|
||||
lindex = (index + 1) % 4
|
||||
rindex = (index + 3) % 4
|
||||
lshift = None
|
||||
rshift = None
|
||||
if index % 2 == 0:
|
||||
rshift = QPointF(shiftPos.x(), 0)
|
||||
lshift = QPointF(0, shiftPos.y())
|
||||
else:
|
||||
lshift = QPointF(shiftPos.x(), 0)
|
||||
rshift = QPointF(0, shiftPos.y())
|
||||
shape.moveVertexBy(rindex, rshift)
|
||||
shape.moveVertexBy(lindex, lshift)
|
||||
|
||||
else:
|
||||
shape.moveVertexBy(index, shiftPos)
|
||||
|
||||
def boundedMoveShape(self, shapes, pos):
|
||||
if type(shapes).__name__ != "list":
|
||||
shapes = [shapes]
|
||||
if self.outOfPixmap(pos):
|
||||
return False # No need to move
|
||||
o1 = pos + self.offsets[0]
|
||||
if self.outOfPixmap(o1):
|
||||
pos -= QPointF(min(0, o1.x()), min(0, o1.y()))
|
||||
o2 = pos + self.offsets[1]
|
||||
if self.outOfPixmap(o2):
|
||||
pos += QPointF(
|
||||
min(0, self.pixmap.width() - o2.x()),
|
||||
min(0, self.pixmap.height() - o2.y()),
|
||||
)
|
||||
# The next line tracks the new position of the cursor
|
||||
# relative to the shape, but also results in making it
|
||||
# a bit "shaky" when nearing the border and allows it to
|
||||
# go outside of the shape's area for some reason. XXX
|
||||
# self.calculateOffsets(self.selectedShape, pos)
|
||||
dp = pos - self.prevPoint
|
||||
if dp:
|
||||
for shape in shapes:
|
||||
shape.moveBy(dp)
|
||||
shape.close()
|
||||
self.prevPoint = pos
|
||||
return True
|
||||
return False
|
||||
|
||||
def deSelectShape(self):
|
||||
if self.selectedShapes:
|
||||
for shape in self.selectedShapes:
|
||||
shape.selected = False
|
||||
self.setHiding(False)
|
||||
self.selectionChanged.emit([])
|
||||
self.update()
|
||||
|
||||
def deleteSelected(self):
|
||||
deleted_shapes = []
|
||||
if self.selectedShapes:
|
||||
for shape in self.selectedShapes:
|
||||
self.shapes.remove(shape)
|
||||
deleted_shapes.append(shape)
|
||||
self.storeShapes()
|
||||
self.selectedShapes = []
|
||||
self.update()
|
||||
|
||||
self.updateShapeIndex()
|
||||
|
||||
return deleted_shapes
|
||||
|
||||
def storeShapes(self):
|
||||
shapesBackup = []
|
||||
for shape in self.shapes:
|
||||
shapesBackup.append(shape.copy())
|
||||
if len(self.shapesBackups) >= 10:
|
||||
self.shapesBackups = self.shapesBackups[-9:]
|
||||
self.shapesBackups.append(shapesBackup)
|
||||
|
||||
def copySelectedShape(self):
|
||||
if self.selectedShapes:
|
||||
self.selectedShapesCopy = [s.copy() for s in self.selectedShapes]
|
||||
self.boundedShiftShapes(self.selectedShapesCopy)
|
||||
self.endMove(copy=True)
|
||||
return self.selectedShapes
|
||||
|
||||
def boundedShiftShapes(self, shapes):
|
||||
# Try to move in one direction, and if it fails in another.
|
||||
# Give up if both fail.
|
||||
for shape in shapes:
|
||||
point = shape[0]
|
||||
offset = QPointF(5.0, 5.0)
|
||||
self.calculateOffsets(shape, point)
|
||||
self.prevPoint = point
|
||||
if not self.boundedMoveShape(shape, point - offset):
|
||||
self.boundedMoveShape(shape, point + offset)
|
||||
|
||||
def paintEvent(self, event):
|
||||
if not self.pixmap:
|
||||
return super(Canvas, self).paintEvent(event)
|
||||
|
||||
p = self._painter
|
||||
p.begin(self)
|
||||
p.setRenderHint(QPainter.Antialiasing)
|
||||
p.setRenderHint(QPainter.HighQualityAntialiasing)
|
||||
p.setRenderHint(QPainter.SmoothPixmapTransform)
|
||||
|
||||
p.scale(self.scale, self.scale)
|
||||
p.translate(self.offsetToCenter())
|
||||
|
||||
p.drawPixmap(0, 0, self.pixmap)
|
||||
Shape.scale = self.scale
|
||||
for shape in self.shapes:
|
||||
if (shape.selected or not self._hideBackround) and self.isVisible(shape):
|
||||
shape.fill = shape.selected or shape == self.hShape
|
||||
shape.paint(p)
|
||||
if self.current:
|
||||
self.current.paint(p)
|
||||
self.line.paint(p)
|
||||
if self.selectedShapesCopy:
|
||||
for s in self.selectedShapesCopy:
|
||||
s.paint(p)
|
||||
|
||||
# Paint rect
|
||||
if self.current is not None and len(self.line) == 2 and not self.fourpoint:
|
||||
# print('Drawing rect')
|
||||
leftTop = self.line[0]
|
||||
rightBottom = self.line[1]
|
||||
rectWidth = rightBottom.x() - leftTop.x()
|
||||
rectHeight = rightBottom.y() - leftTop.y()
|
||||
p.setPen(self.drawingRectColor)
|
||||
brush = QBrush(Qt.BDiagPattern)
|
||||
p.setBrush(brush)
|
||||
p.drawRect(
|
||||
int(leftTop.x()), int(leftTop.y()), int(rectWidth), int(rectHeight)
|
||||
)
|
||||
|
||||
# ADD:
|
||||
if (
|
||||
self.fillDrawing()
|
||||
and self.fourpoint
|
||||
and self.current is not None
|
||||
and len(self.current.points) >= 2
|
||||
):
|
||||
print("paint event")
|
||||
drawing_shape = self.current.copy()
|
||||
drawing_shape.addPoint(self.line[1])
|
||||
drawing_shape.fill = True
|
||||
drawing_shape.paint(p)
|
||||
|
||||
if (
|
||||
self.drawing()
|
||||
and not self.prevPoint.isNull()
|
||||
and not self.outOfPixmap(self.prevPoint)
|
||||
):
|
||||
p.setPen(QColor(0, 0, 0))
|
||||
p.drawLine(
|
||||
int(self.prevPoint.x()),
|
||||
0,
|
||||
int(self.prevPoint.x()),
|
||||
int(self.pixmap.height()),
|
||||
)
|
||||
p.drawLine(
|
||||
0,
|
||||
int(self.prevPoint.y()),
|
||||
int(self.pixmap.width()),
|
||||
int(self.prevPoint.y()),
|
||||
)
|
||||
|
||||
self.setAutoFillBackground(True)
|
||||
if self.verified:
|
||||
pal = self.palette()
|
||||
pal.setColor(self.backgroundRole(), QColor(184, 239, 38, 128))
|
||||
self.setPalette(pal)
|
||||
else:
|
||||
pal = self.palette()
|
||||
pal.setColor(self.backgroundRole(), QColor(232, 232, 232, 255))
|
||||
self.setPalette(pal)
|
||||
|
||||
# adaptive BBOX label & index font size
|
||||
if self.pixmap:
|
||||
h, w = self.pixmap.size().height(), self.pixmap.size().width()
|
||||
fontszie = int(max(h, w) / 48)
|
||||
for s in self.shapes:
|
||||
s.fontsize = fontszie
|
||||
|
||||
p.end()
|
||||
|
||||
def fillDrawing(self):
|
||||
return self._fill_drawing
|
||||
|
||||
def transformPos(self, point):
|
||||
"""Convert from widget-logical coordinates to painter-logical coordinates."""
|
||||
return point / self.scale - self.offsetToCenter()
|
||||
|
||||
def offsetToCenter(self):
|
||||
s = self.scale
|
||||
area = super(Canvas, self).size()
|
||||
w, h = self.pixmap.width() * s, self.pixmap.height() * s
|
||||
aw, ah = area.width(), area.height()
|
||||
x = (aw - w) / (2 * s) if aw > w else 0
|
||||
y = (ah - h) / (2 * s) if ah > h else 0
|
||||
return QPointF(x, y)
|
||||
|
||||
def outOfPixmap(self, p):
|
||||
w, h = self.pixmap.width(), self.pixmap.height()
|
||||
return not (0 <= p.x() <= w and 0 <= p.y() <= h)
|
||||
|
||||
def finalise(self):
|
||||
assert self.current
|
||||
if self.current.points[0] == self.current.points[-1]:
|
||||
# print('finalse')
|
||||
self.current = None
|
||||
self.drawingPolygon.emit(False)
|
||||
self.update()
|
||||
return
|
||||
|
||||
self.current.close()
|
||||
self.current.idx = len(self.shapes) # add current box index
|
||||
self.shapes.append(self.current)
|
||||
self.current = None
|
||||
self.setHiding(False)
|
||||
self.newShape.emit()
|
||||
self.update()
|
||||
|
||||
def closeEnough(self, p1, p2):
|
||||
# d = distance(p1 - p2)
|
||||
# m = (p1-p2).manhattanLength()
|
||||
# print "d %.2f, m %d, %.2f" % (d, m, d - m)
|
||||
return distance(p1 - p2) < self.epsilon
|
||||
|
||||
# These two, along with a call to adjustSize are required for the
|
||||
# scroll area.
|
||||
def sizeHint(self):
|
||||
return self.minimumSizeHint()
|
||||
|
||||
def minimumSizeHint(self):
|
||||
if self.pixmap:
|
||||
return self.scale * self.pixmap.size()
|
||||
return super(Canvas, self).minimumSizeHint()
|
||||
|
||||
def wheelEvent(self, ev):
|
||||
qt_version = 4 if hasattr(ev, "delta") else 5
|
||||
if qt_version == 4:
|
||||
if ev.orientation() == Qt.Vertical:
|
||||
v_delta = ev.delta()
|
||||
h_delta = 0
|
||||
else:
|
||||
h_delta = ev.delta()
|
||||
v_delta = 0
|
||||
else:
|
||||
delta = ev.angleDelta()
|
||||
h_delta = delta.x()
|
||||
v_delta = delta.y()
|
||||
|
||||
mods = ev.modifiers()
|
||||
if Qt.ControlModifier == int(mods) and v_delta:
|
||||
self.zoomRequest.emit(v_delta)
|
||||
else:
|
||||
v_delta and self.scrollRequest.emit(v_delta, Qt.Vertical)
|
||||
h_delta and self.scrollRequest.emit(h_delta, Qt.Horizontal)
|
||||
ev.accept()
|
||||
|
||||
def keyPressEvent(self, ev):
|
||||
key = ev.key()
|
||||
shapesBackup = copy.deepcopy(self.shapes)
|
||||
if len(shapesBackup) == 0:
|
||||
return
|
||||
self.shapesBackups.pop()
|
||||
self.shapesBackups.append(shapesBackup)
|
||||
if key == Qt.Key_Escape and self.current:
|
||||
print("ESC press")
|
||||
self.current = None
|
||||
self.drawingPolygon.emit(False)
|
||||
self.update()
|
||||
elif key == Qt.Key_Return and self.canCloseShape():
|
||||
self.finalise()
|
||||
elif key == Qt.Key_Left and self.selectedShapes:
|
||||
self.moveOnePixel("Left")
|
||||
elif key == Qt.Key_Right and self.selectedShapes:
|
||||
self.moveOnePixel("Right")
|
||||
elif key == Qt.Key_Up and self.selectedShapes:
|
||||
self.moveOnePixel("Up")
|
||||
elif key == Qt.Key_Down and self.selectedShapes:
|
||||
self.moveOnePixel("Down")
|
||||
elif key == Qt.Key_X and self.selectedShapes:
|
||||
for i in range(len(self.selectedShapes)):
|
||||
self.selectedShape = self.selectedShapes[i]
|
||||
if self.rotateOutOfBound(0.01):
|
||||
continue
|
||||
self.selectedShape.rotate(0.01)
|
||||
self.shapeMoved.emit()
|
||||
self.update()
|
||||
|
||||
elif key == Qt.Key_C and self.selectedShapes:
|
||||
for i in range(len(self.selectedShapes)):
|
||||
self.selectedShape = self.selectedShapes[i]
|
||||
if self.rotateOutOfBound(-0.01):
|
||||
continue
|
||||
self.selectedShape.rotate(-0.01)
|
||||
self.shapeMoved.emit()
|
||||
self.update()
|
||||
|
||||
def rotateOutOfBound(self, angle):
|
||||
for shape in range(len(self.selectedShapes)):
|
||||
self.selectedShape = self.selectedShapes[shape]
|
||||
for i, p in enumerate(self.selectedShape.points):
|
||||
if self.outOfPixmap(self.selectedShape.rotatePoint(p, angle)):
|
||||
return True
|
||||
return False
|
||||
|
||||
def moveOnePixel(self, direction):
|
||||
# print(self.selectedShape.points)
|
||||
self.selectCount = len(self.selectedShapes)
|
||||
self.selectCountShape = True
|
||||
for i in range(len(self.selectedShapes)):
|
||||
self.selectedShape = self.selectedShapes[i]
|
||||
if direction == "Left" and not self.moveOutOfBound(QPointF(-1.0, 0)):
|
||||
# print("move Left one pixel")
|
||||
self.selectedShape.points[0] += QPointF(-1.0, 0)
|
||||
self.selectedShape.points[1] += QPointF(-1.0, 0)
|
||||
self.selectedShape.points[2] += QPointF(-1.0, 0)
|
||||
self.selectedShape.points[3] += QPointF(-1.0, 0)
|
||||
elif direction == "Right" and not self.moveOutOfBound(QPointF(1.0, 0)):
|
||||
# print("move Right one pixel")
|
||||
self.selectedShape.points[0] += QPointF(1.0, 0)
|
||||
self.selectedShape.points[1] += QPointF(1.0, 0)
|
||||
self.selectedShape.points[2] += QPointF(1.0, 0)
|
||||
self.selectedShape.points[3] += QPointF(1.0, 0)
|
||||
elif direction == "Up" and not self.moveOutOfBound(QPointF(0, -1.0)):
|
||||
# print("move Up one pixel")
|
||||
self.selectedShape.points[0] += QPointF(0, -1.0)
|
||||
self.selectedShape.points[1] += QPointF(0, -1.0)
|
||||
self.selectedShape.points[2] += QPointF(0, -1.0)
|
||||
self.selectedShape.points[3] += QPointF(0, -1.0)
|
||||
elif direction == "Down" and not self.moveOutOfBound(QPointF(0, 1.0)):
|
||||
# print("move Down one pixel")
|
||||
self.selectedShape.points[0] += QPointF(0, 1.0)
|
||||
self.selectedShape.points[1] += QPointF(0, 1.0)
|
||||
self.selectedShape.points[2] += QPointF(0, 1.0)
|
||||
self.selectedShape.points[3] += QPointF(0, 1.0)
|
||||
shapesBackup = []
|
||||
shapesBackup = copy.deepcopy(self.shapes)
|
||||
self.shapesBackups.append(shapesBackup)
|
||||
self.shapeMoved.emit()
|
||||
self.repaint()
|
||||
|
||||
def moveOutOfBound(self, step):
|
||||
points = [p1 + p2 for p1, p2 in zip(self.selectedShape.points, [step] * 4)]
|
||||
return True in map(self.outOfPixmap, points)
|
||||
|
||||
def setLastLabel(self, text, line_color=None, fill_color=None, key_cls=None):
|
||||
assert text
|
||||
self.shapes[-1].label = text
|
||||
if line_color:
|
||||
self.shapes[-1].line_color = line_color
|
||||
|
||||
if fill_color:
|
||||
self.shapes[-1].fill_color = fill_color
|
||||
|
||||
if key_cls:
|
||||
self.shapes[-1].key_cls = key_cls
|
||||
|
||||
self.storeShapes()
|
||||
|
||||
return self.shapes[-1]
|
||||
|
||||
def undoLastLine(self):
|
||||
assert self.shapes
|
||||
self.current = self.shapes.pop()
|
||||
self.current.setOpen()
|
||||
self.line.points = [self.current[-1], self.current[0]]
|
||||
self.drawingPolygon.emit(True)
|
||||
|
||||
def undoLastPoint(self):
|
||||
if not self.current or self.current.isClosed():
|
||||
return
|
||||
self.current.popPoint()
|
||||
if len(self.current) > 0:
|
||||
self.line[0] = self.current[-1]
|
||||
else:
|
||||
self.current = None
|
||||
self.drawingPolygon.emit(False)
|
||||
self.repaint()
|
||||
|
||||
def resetAllLines(self):
|
||||
assert self.shapes
|
||||
self.current = self.shapes.pop()
|
||||
self.current.setOpen()
|
||||
self.line.points = [self.current[-1], self.current[0]]
|
||||
self.drawingPolygon.emit(True)
|
||||
self.current = None
|
||||
self.drawingPolygon.emit(False)
|
||||
self.update()
|
||||
|
||||
def loadPixmap(self, pixmap):
|
||||
self.pixmap = pixmap
|
||||
self.shapes = []
|
||||
self.repaint()
|
||||
|
||||
def loadShapes(self, shapes, replace=True):
|
||||
if replace:
|
||||
self.shapes = list(shapes)
|
||||
else:
|
||||
self.shapes.extend(shapes)
|
||||
self.current = None
|
||||
self.hShape = None
|
||||
self.hVertex = None
|
||||
# self.hEdge = None
|
||||
self.storeShapes()
|
||||
self.updateShapeIndex()
|
||||
self.repaint()
|
||||
|
||||
def setShapeVisible(self, shape, value):
|
||||
self.visible[shape] = value
|
||||
self.repaint()
|
||||
|
||||
def currentCursor(self):
|
||||
cursor = QApplication.overrideCursor()
|
||||
if cursor is not None:
|
||||
cursor = cursor.shape()
|
||||
return cursor
|
||||
|
||||
def overrideCursor(self, cursor):
|
||||
self._cursor = cursor
|
||||
if self.currentCursor() is None:
|
||||
QApplication.setOverrideCursor(cursor)
|
||||
else:
|
||||
QApplication.changeOverrideCursor(cursor)
|
||||
|
||||
def restoreCursor(self):
|
||||
QApplication.restoreOverrideCursor()
|
||||
|
||||
def resetState(self):
|
||||
self.restoreCursor()
|
||||
self.pixmap = None
|
||||
self.update()
|
||||
self.shapesBackups = []
|
||||
|
||||
def setDrawingShapeToSquare(self, status):
|
||||
self.drawSquare = status
|
||||
|
||||
def restoreShape(self):
|
||||
if not self.isShapeRestorable:
|
||||
return
|
||||
|
||||
self.shapesBackups.pop() # latest
|
||||
shapesBackup = self.shapesBackups.pop()
|
||||
self.shapes = shapesBackup
|
||||
self.selectedShapes = []
|
||||
for shape in self.shapes:
|
||||
shape.selected = False
|
||||
self.updateShapeIndex()
|
||||
self.repaint()
|
||||
|
||||
@property
|
||||
def isShapeRestorable(self):
|
||||
if len(self.shapesBackups) < 2:
|
||||
return False
|
||||
return True
|
||||
|
||||
def updateShapeIndex(self):
|
||||
for i in range(len(self.shapes)):
|
||||
self.shapes[i].idx = i
|
||||
self.update()
|
|
@ -1,48 +0,0 @@
|
|||
# Copyright (c) <2015-Present> Tzutalin
|
||||
# Copyright (C) 2013 MIT, Computer Science and Artificial Intelligence Laboratory. Bryan Russell, Antonio Torralba,
|
||||
# William T. Freeman. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
# associated documentation files (the "Software"), to deal in the Software without restriction, including without
|
||||
# limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
# Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of
|
||||
# the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
# NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
||||
# SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
try:
|
||||
from PyQt5.QtGui import *
|
||||
from PyQt5.QtCore import *
|
||||
from PyQt5.QtWidgets import QColorDialog, QDialogButtonBox
|
||||
except ImportError:
|
||||
from PyQt4.QtGui import *
|
||||
from PyQt4.QtCore import *
|
||||
|
||||
BB = QDialogButtonBox
|
||||
|
||||
|
||||
class ColorDialog(QColorDialog):
|
||||
def __init__(self, parent=None):
|
||||
super(ColorDialog, self).__init__(parent)
|
||||
self.setOption(QColorDialog.ShowAlphaChannel)
|
||||
# The Mac native dialog does not support our restore button.
|
||||
self.setOption(QColorDialog.DontUseNativeDialog)
|
||||
# Add a restore defaults button.
|
||||
# The default is set at invocation time, so that it
|
||||
# works across dialogs for different elements.
|
||||
self.default = None
|
||||
self.bb = self.layout().itemAt(1).widget()
|
||||
self.bb.addButton(BB.RestoreDefaults)
|
||||
self.bb.clicked.connect(self.checkRestore)
|
||||
|
||||
def getColor(self, value=None, title=None, default=None):
|
||||
self.default = default
|
||||
if title:
|
||||
self.setWindowTitle(title)
|
||||
if value:
|
||||
self.setCurrentColor(value)
|
||||
return self.currentColor() if self.exec_() else None
|
||||
|
||||
def checkRestore(self, button):
|
||||
if self.bb.buttonRole(button) & BB.ResetRole and self.default:
|
||||
self.setCurrentColor(self.default)
|
|
@ -1,32 +0,0 @@
|
|||
# Copyright (c) <2015-Present> Tzutalin
|
||||
# Copyright (C) 2013 MIT, Computer Science and Artificial Intelligence Laboratory. Bryan Russell, Antonio Torralba,
|
||||
# William T. Freeman. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
# associated documentation files (the "Software"), to deal in the Software without restriction, including without
|
||||
# limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
# Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of
|
||||
# the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
# NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
||||
# SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
SETTING_FILENAME = "filename"
|
||||
SETTING_RECENT_FILES = "recentFiles"
|
||||
SETTING_WIN_SIZE = "window/size"
|
||||
SETTING_WIN_POSE = "window/position"
|
||||
SETTING_WIN_GEOMETRY = "window/geometry"
|
||||
SETTING_LINE_COLOR = "line/color"
|
||||
SETTING_FILL_COLOR = "fill/color"
|
||||
SETTING_ADVANCE_MODE = "advanced"
|
||||
SETTING_WIN_STATE = "window/state"
|
||||
SETTING_SAVE_DIR = "savedir"
|
||||
SETTING_PAINT_LABEL = "paintlabel"
|
||||
SETTING_PAINT_INDEX = "paintindex"
|
||||
SETTING_LAST_OPEN_DIR = "lastOpenDir"
|
||||
SETTING_AUTO_SAVE = "autosave"
|
||||
SETTING_SINGLE_CLASS = "singleclass"
|
||||
FORMAT_PASCALVOC = "PascalVOC"
|
||||
FORMAT_YOLO = "YOLO"
|
||||
SETTING_DRAW_SQUARE = "draw/square"
|
||||
SETTING_LABEL_FILE_FORMAT = "labelFileFormat"
|
||||
DEFAULT_ENCODING = "utf-8"
|
|
@ -1,144 +0,0 @@
|
|||
# Copyright (c) <2015-Present> Tzutalin
|
||||
# Copyright (C) 2013 MIT, Computer Science and Artificial Intelligence Laboratory. Bryan Russell, Antonio Torralba,
|
||||
# William T. Freeman. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
# associated documentation files (the "Software"), to deal in the Software without restriction, including without
|
||||
# limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
# Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of
|
||||
# the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
# NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
||||
# SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf8 -*-
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
from libs.constants import DEFAULT_ENCODING
|
||||
import os
|
||||
|
||||
JSON_EXT = ".json"
|
||||
ENCODE_METHOD = DEFAULT_ENCODING
|
||||
|
||||
|
||||
class CreateMLWriter:
|
||||
def __init__(
|
||||
self,
|
||||
foldername,
|
||||
filename,
|
||||
imgsize,
|
||||
shapes,
|
||||
outputfile,
|
||||
databasesrc="Unknown",
|
||||
localimgpath=None,
|
||||
):
|
||||
self.foldername = foldername
|
||||
self.filename = filename
|
||||
self.databasesrc = databasesrc
|
||||
self.imgsize = imgsize
|
||||
self.boxlist = []
|
||||
self.localimgpath = localimgpath
|
||||
self.verified = False
|
||||
self.shapes = shapes
|
||||
self.outputfile = outputfile
|
||||
|
||||
def write(self):
|
||||
if os.path.isfile(self.outputfile):
|
||||
with open(self.outputfile, "r") as file:
|
||||
input_data = file.read()
|
||||
outputdict = json.loads(input_data)
|
||||
else:
|
||||
outputdict = []
|
||||
|
||||
outputimagedict = {"image": self.filename, "annotations": []}
|
||||
|
||||
for shape in self.shapes:
|
||||
points = shape["points"]
|
||||
|
||||
x1 = points[0][0]
|
||||
y1 = points[0][1]
|
||||
x2 = points[1][0]
|
||||
y2 = points[2][1]
|
||||
|
||||
height, width, x, y = self.calculate_coordinates(x1, x2, y1, y2)
|
||||
|
||||
shapedict = {
|
||||
"label": shape["label"],
|
||||
"coordinates": {"x": x, "y": y, "width": width, "height": height},
|
||||
}
|
||||
outputimagedict["annotations"].append(shapedict)
|
||||
|
||||
# check if image already in output
|
||||
exists = False
|
||||
for i in range(0, len(outputdict)):
|
||||
if outputdict[i]["image"] == outputimagedict["image"]:
|
||||
exists = True
|
||||
outputdict[i] = outputimagedict
|
||||
break
|
||||
|
||||
if not exists:
|
||||
outputdict.append(outputimagedict)
|
||||
|
||||
Path(self.outputfile).write_text(json.dumps(outputdict), ENCODE_METHOD)
|
||||
|
||||
def calculate_coordinates(self, x1, x2, y1, y2):
|
||||
if x1 < x2:
|
||||
xmin = x1
|
||||
xmax = x2
|
||||
else:
|
||||
xmin = x2
|
||||
xmax = x1
|
||||
if y1 < y2:
|
||||
ymin = y1
|
||||
ymax = y2
|
||||
else:
|
||||
ymin = y2
|
||||
ymax = y1
|
||||
width = xmax - xmin
|
||||
if width < 0:
|
||||
width = width * -1
|
||||
height = ymax - ymin
|
||||
# x and y from center of rect
|
||||
x = xmin + width / 2
|
||||
y = ymin + height / 2
|
||||
return height, width, x, y
|
||||
|
||||
|
||||
class CreateMLReader:
|
||||
def __init__(self, jsonpath, filepath):
|
||||
self.jsonpath = jsonpath
|
||||
self.shapes = []
|
||||
self.verified = False
|
||||
self.filename = filepath.split("/")[-1:][0]
|
||||
try:
|
||||
self.parse_json()
|
||||
except ValueError:
|
||||
print("JSON decoding failed")
|
||||
|
||||
def parse_json(self):
|
||||
with open(self.jsonpath, "r") as file:
|
||||
inputdata = file.read()
|
||||
|
||||
outputdict = json.loads(inputdata)
|
||||
self.verified = True
|
||||
|
||||
if len(self.shapes) > 0:
|
||||
self.shapes = []
|
||||
for image in outputdict:
|
||||
if image["image"] == self.filename:
|
||||
for shape in image["annotations"]:
|
||||
self.add_shape(shape["label"], shape["coordinates"])
|
||||
|
||||
def add_shape(self, label, bndbox):
|
||||
xmin = bndbox["x"] - (bndbox["width"] / 2)
|
||||
ymin = bndbox["y"] - (bndbox["height"] / 2)
|
||||
|
||||
xmax = bndbox["x"] + (bndbox["width"] / 2)
|
||||
ymax = bndbox["y"] + (bndbox["height"] / 2)
|
||||
|
||||
points = [(xmin, ymin), (xmax, ymin), (xmax, ymax), (xmin, ymax)]
|
||||
self.shapes.append((label, points, None, None, True))
|
||||
|
||||
def get_shapes(self):
|
||||
return self.shapes
|
|
@ -1,33 +0,0 @@
|
|||
# !/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
from PyQt5.QtCore import QModelIndex
|
||||
from PyQt5.QtWidgets import QListWidget
|
||||
|
||||
|
||||
class EditInList(QListWidget):
|
||||
def __init__(self):
|
||||
super(EditInList, self).__init__()
|
||||
self.edited_item = None
|
||||
|
||||
def item_clicked(self, modelindex: QModelIndex):
|
||||
try:
|
||||
if self.edited_item is not None:
|
||||
self.closePersistentEditor(self.edited_item)
|
||||
except:
|
||||
self.edited_item = self.currentItem()
|
||||
|
||||
self.edited_item = self.item(modelindex.row())
|
||||
self.openPersistentEditor(self.edited_item)
|
||||
self.editItem(self.edited_item)
|
||||
|
||||
def mouseDoubleClickEvent(self, event):
|
||||
pass
|
||||
|
||||
def leaveEvent(self, event):
|
||||
pass
|
||||
|
||||
def keyPressEvent(self, event) -> None:
|
||||
# close edit
|
||||
if event.key() in [16777220, 16777221]:
|
||||
for i in range(self.count()):
|
||||
self.closePersistentEditor(self.item(i))
|
|
@ -1,41 +0,0 @@
|
|||
# Copyright (c) <2015-Present> Tzutalin
|
||||
# Copyright (C) 2013 MIT, Computer Science and Artificial Intelligence Laboratory. Bryan Russell, Antonio Torralba,
|
||||
# William T. Freeman. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
# associated documentation files (the "Software"), to deal in the Software without restriction, including without
|
||||
# limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
# Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of
|
||||
# the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
# NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
||||
# SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
import sys
|
||||
|
||||
try:
|
||||
from PyQt5.QtGui import *
|
||||
from PyQt5.QtCore import *
|
||||
from PyQt5.QtWidgets import *
|
||||
except ImportError:
|
||||
# needed for py3+qt4
|
||||
# Ref:
|
||||
# http://pyqt.sourceforge.net/Docs/PyQt4/incompatible_apis.html
|
||||
# http://stackoverflow.com/questions/21217399/pyqt4-qtcore-qvariant-object-instead-of-a-string
|
||||
if sys.version_info.major >= 3:
|
||||
import sip
|
||||
|
||||
sip.setapi("QVariant", 2)
|
||||
from PyQt4.QtGui import *
|
||||
from PyQt4.QtCore import *
|
||||
|
||||
# PyQt5: TypeError: unhashable type: 'QListWidgetItem'
|
||||
|
||||
|
||||
class HashableQListWidgetItem(QListWidgetItem):
|
||||
def __init__(self, *args):
|
||||
super(HashableQListWidgetItem, self).__init__(*args)
|
||||
|
||||
def __hash__(self):
|
||||
return hash(id(self))
|
|
@ -1,208 +0,0 @@
|
|||
import re
|
||||
|
||||
from PyQt5 import QtCore
|
||||
from PyQt5 import QtGui
|
||||
from PyQt5 import QtWidgets
|
||||
from PyQt5.Qt import QT_VERSION_STR
|
||||
from libs.utils import newIcon, labelValidator
|
||||
|
||||
QT5 = QT_VERSION_STR[0] == "5"
|
||||
|
||||
|
||||
# TODO(unknown):
|
||||
# - Calculate optimal position so as not to go out of screen area.
|
||||
|
||||
|
||||
class KeyQLineEdit(QtWidgets.QLineEdit):
|
||||
def setListWidget(self, list_widget):
|
||||
self.list_widget = list_widget
|
||||
|
||||
def keyPressEvent(self, e):
|
||||
if e.key() in [QtCore.Qt.Key_Up, QtCore.Qt.Key_Down]:
|
||||
self.list_widget.keyPressEvent(e)
|
||||
else:
|
||||
super(KeyQLineEdit, self).keyPressEvent(e)
|
||||
|
||||
|
||||
class KeyDialog(QtWidgets.QDialog):
|
||||
def __init__(
|
||||
self,
|
||||
text="Enter object label",
|
||||
parent=None,
|
||||
labels=None,
|
||||
sort_labels=True,
|
||||
show_text_field=True,
|
||||
completion="startswith",
|
||||
fit_to_content=None,
|
||||
flags=None,
|
||||
):
|
||||
if fit_to_content is None:
|
||||
fit_to_content = {"row": False, "column": True}
|
||||
self._fit_to_content = fit_to_content
|
||||
|
||||
super(KeyDialog, self).__init__(parent)
|
||||
self.edit = KeyQLineEdit()
|
||||
self.edit.setPlaceholderText(text)
|
||||
self.edit.setValidator(labelValidator())
|
||||
self.edit.editingFinished.connect(self.postProcess)
|
||||
if flags:
|
||||
self.edit.textChanged.connect(self.updateFlags)
|
||||
|
||||
layout = QtWidgets.QVBoxLayout()
|
||||
if show_text_field:
|
||||
layout_edit = QtWidgets.QHBoxLayout()
|
||||
layout_edit.addWidget(self.edit, 6)
|
||||
layout.addLayout(layout_edit)
|
||||
# buttons
|
||||
self.buttonBox = bb = QtWidgets.QDialogButtonBox(
|
||||
QtWidgets.QDialogButtonBox.Ok | QtWidgets.QDialogButtonBox.Cancel,
|
||||
QtCore.Qt.Horizontal,
|
||||
self,
|
||||
)
|
||||
bb.button(bb.Ok).setIcon(newIcon("done"))
|
||||
bb.button(bb.Cancel).setIcon(newIcon("undo"))
|
||||
bb.accepted.connect(self.validate)
|
||||
bb.rejected.connect(self.reject)
|
||||
layout.addWidget(bb)
|
||||
# label_list
|
||||
self.labelList = QtWidgets.QListWidget()
|
||||
if self._fit_to_content["row"]:
|
||||
self.labelList.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
|
||||
if self._fit_to_content["column"]:
|
||||
self.labelList.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
|
||||
self._sort_labels = sort_labels
|
||||
if labels:
|
||||
self.labelList.addItems(labels)
|
||||
if self._sort_labels:
|
||||
self.labelList.sortItems()
|
||||
else:
|
||||
self.labelList.setDragDropMode(QtWidgets.QAbstractItemView.InternalMove)
|
||||
self.labelList.currentItemChanged.connect(self.labelSelected)
|
||||
self.labelList.itemDoubleClicked.connect(self.labelDoubleClicked)
|
||||
self.edit.setListWidget(self.labelList)
|
||||
layout.addWidget(self.labelList)
|
||||
# label_flags
|
||||
if flags is None:
|
||||
flags = {}
|
||||
self._flags = flags
|
||||
self.flagsLayout = QtWidgets.QVBoxLayout()
|
||||
self.resetFlags()
|
||||
layout.addItem(self.flagsLayout)
|
||||
self.edit.textChanged.connect(self.updateFlags)
|
||||
self.setLayout(layout)
|
||||
# completion
|
||||
completer = QtWidgets.QCompleter()
|
||||
if not QT5 and completion != "startswith":
|
||||
completion = "startswith"
|
||||
if completion == "startswith":
|
||||
completer.setCompletionMode(QtWidgets.QCompleter.InlineCompletion)
|
||||
# Default settings.
|
||||
# completer.setFilterMode(QtCore.Qt.MatchStartsWith)
|
||||
elif completion == "contains":
|
||||
completer.setCompletionMode(QtWidgets.QCompleter.PopupCompletion)
|
||||
completer.setFilterMode(QtCore.Qt.MatchContains)
|
||||
else:
|
||||
raise ValueError("Unsupported completion: {}".format(completion))
|
||||
completer.setModel(self.labelList.model())
|
||||
self.edit.setCompleter(completer)
|
||||
|
||||
def addLabelHistory(self, label):
|
||||
if self.labelList.findItems(label, QtCore.Qt.MatchExactly):
|
||||
return
|
||||
self.labelList.addItem(label)
|
||||
if self._sort_labels:
|
||||
self.labelList.sortItems()
|
||||
|
||||
def labelSelected(self, item):
|
||||
self.edit.setText(item.text())
|
||||
|
||||
def validate(self):
|
||||
text = self.edit.text()
|
||||
if hasattr(text, "strip"):
|
||||
text = text.strip()
|
||||
else:
|
||||
text = text.trimmed()
|
||||
if text:
|
||||
self.accept()
|
||||
|
||||
def labelDoubleClicked(self, item):
|
||||
self.validate()
|
||||
|
||||
def postProcess(self):
|
||||
text = self.edit.text()
|
||||
if hasattr(text, "strip"):
|
||||
text = text.strip()
|
||||
else:
|
||||
text = text.trimmed()
|
||||
self.edit.setText(text)
|
||||
|
||||
def updateFlags(self, label_new):
|
||||
# keep state of shared flags
|
||||
flags_old = self.getFlags()
|
||||
|
||||
flags_new = {}
|
||||
for pattern, keys in self._flags.items():
|
||||
if re.match(pattern, label_new):
|
||||
for key in keys:
|
||||
flags_new[key] = flags_old.get(key, False)
|
||||
self.setFlags(flags_new)
|
||||
|
||||
def deleteFlags(self):
|
||||
for i in reversed(range(self.flagsLayout.count())):
|
||||
item = self.flagsLayout.itemAt(i).widget()
|
||||
self.flagsLayout.removeWidget(item)
|
||||
item.setParent(None)
|
||||
|
||||
def resetFlags(self, label=""):
|
||||
flags = {}
|
||||
for pattern, keys in self._flags.items():
|
||||
if re.match(pattern, label):
|
||||
for key in keys:
|
||||
flags[key] = False
|
||||
self.setFlags(flags)
|
||||
|
||||
def setFlags(self, flags):
|
||||
self.deleteFlags()
|
||||
for key in flags:
|
||||
item = QtWidgets.QCheckBox(key, self)
|
||||
item.setChecked(flags[key])
|
||||
self.flagsLayout.addWidget(item)
|
||||
item.show()
|
||||
|
||||
def getFlags(self):
|
||||
flags = {}
|
||||
for i in range(self.flagsLayout.count()):
|
||||
item = self.flagsLayout.itemAt(i).widget()
|
||||
flags[item.text()] = item.isChecked()
|
||||
return flags
|
||||
|
||||
def popUp(self, text=None, move=True, flags=None):
|
||||
if self._fit_to_content["row"]:
|
||||
self.labelList.setMinimumHeight(
|
||||
self.labelList.sizeHintForRow(0) * self.labelList.count() + 2
|
||||
)
|
||||
if self._fit_to_content["column"]:
|
||||
self.labelList.setMinimumWidth(self.labelList.sizeHintForColumn(0) + 2)
|
||||
# if text is None, the previous label in self.edit is kept
|
||||
if text is None:
|
||||
text = self.edit.text()
|
||||
if flags:
|
||||
self.setFlags(flags)
|
||||
else:
|
||||
self.resetFlags(text)
|
||||
self.edit.setText(text)
|
||||
self.edit.setSelection(0, len(text))
|
||||
|
||||
items = self.labelList.findItems(text, QtCore.Qt.MatchFixedString)
|
||||
if items:
|
||||
if len(items) != 1:
|
||||
self.labelList.setCurrentItem(items[0])
|
||||
row = self.labelList.row(items[0])
|
||||
self.edit.completer().setCurrentRow(row)
|
||||
self.edit.setFocus(QtCore.Qt.PopupFocusReason)
|
||||
if move:
|
||||
self.move(QtGui.QCursor.pos())
|
||||
if self.exec_():
|
||||
return self.edit.text(), self.getFlags()
|
||||
else:
|
||||
return None, None
|
|
@ -1,88 +0,0 @@
|
|||
import PIL.Image
|
||||
import numpy as np
|
||||
|
||||
|
||||
def rgb2hsv(rgb):
|
||||
# type: (np.ndarray) -> np.ndarray
|
||||
"""Convert rgb to hsv.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
rgb: numpy.ndarray, (H, W, 3), np.uint8
|
||||
Input rgb image.
|
||||
|
||||
Returns
|
||||
-------
|
||||
hsv: numpy.ndarray, (H, W, 3), np.uint8
|
||||
Output hsv image.
|
||||
|
||||
"""
|
||||
hsv = PIL.Image.fromarray(rgb, mode="RGB")
|
||||
hsv = hsv.convert("HSV")
|
||||
hsv = np.array(hsv)
|
||||
return hsv
|
||||
|
||||
|
||||
def hsv2rgb(hsv):
|
||||
# type: (np.ndarray) -> np.ndarray
|
||||
"""Convert hsv to rgb.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
hsv: numpy.ndarray, (H, W, 3), np.uint8
|
||||
Input hsv image.
|
||||
|
||||
Returns
|
||||
-------
|
||||
rgb: numpy.ndarray, (H, W, 3), np.uint8
|
||||
Output rgb image.
|
||||
|
||||
"""
|
||||
rgb = PIL.Image.fromarray(hsv, mode="HSV")
|
||||
rgb = rgb.convert("RGB")
|
||||
rgb = np.array(rgb)
|
||||
return rgb
|
||||
|
||||
|
||||
def label_colormap(n_label=256, value=None):
|
||||
"""Label colormap.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
n_label: int
|
||||
Number of labels (default: 256).
|
||||
value: float or int
|
||||
Value scale or value of label color in HSV space.
|
||||
|
||||
Returns
|
||||
-------
|
||||
cmap: numpy.ndarray, (N, 3), numpy.uint8
|
||||
Label id to colormap.
|
||||
|
||||
"""
|
||||
|
||||
def bitget(byteval, idx):
|
||||
return (byteval & (1 << idx)) != 0
|
||||
|
||||
cmap = np.zeros((n_label, 3), dtype=np.uint8)
|
||||
for i in range(0, n_label):
|
||||
id = i
|
||||
r, g, b = 0, 0, 0
|
||||
for j in range(0, 8):
|
||||
r = np.bitwise_or(r, (bitget(id, 0) << 7 - j))
|
||||
g = np.bitwise_or(g, (bitget(id, 1) << 7 - j))
|
||||
b = np.bitwise_or(b, (bitget(id, 2) << 7 - j))
|
||||
id = id >> 3
|
||||
cmap[i, 0] = r
|
||||
cmap[i, 1] = g
|
||||
cmap[i, 2] = b
|
||||
|
||||
if value is not None:
|
||||
hsv = rgb2hsv(cmap.reshape(1, -1, 3))
|
||||
if isinstance(value, float):
|
||||
hsv[:, 1:, 2] = hsv[:, 1:, 2].astype(float) * value
|
||||
else:
|
||||
assert isinstance(value, int)
|
||||
hsv[:, 1:, 2] = value
|
||||
cmap = hsv2rgb(hsv).reshape(-1, 3)
|
||||
return cmap
|
|
@ -1,114 +0,0 @@
|
|||
# Copyright (c) <2015-Present> Tzutalin
|
||||
# Copyright (C) 2013 MIT, Computer Science and Artificial Intelligence Laboratory. Bryan Russell, Antonio Torralba,
|
||||
# William T. Freeman. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
# associated documentation files (the "Software"), to deal in the Software without restriction, including without
|
||||
# limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
# Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of
|
||||
# the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
# NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
||||
# SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
try:
|
||||
from PyQt5.QtGui import *
|
||||
from PyQt5.QtCore import *
|
||||
from PyQt5.QtWidgets import *
|
||||
except ImportError:
|
||||
from PyQt4.QtGui import *
|
||||
from PyQt4.QtCore import *
|
||||
|
||||
from libs.utils import newIcon, labelValidator
|
||||
|
||||
BB = QDialogButtonBox
|
||||
|
||||
|
||||
class LabelDialog(QDialog):
|
||||
def __init__(self, text="Enter object label", parent=None, listItem=None):
|
||||
super(LabelDialog, self).__init__(parent)
|
||||
|
||||
self.edit = QLineEdit() # OLD
|
||||
# self.edit = QTextEdit()
|
||||
self.edit.setText(text)
|
||||
# self.edit.setValidator(labelValidator()) # 验证有效性
|
||||
self.edit.editingFinished.connect(self.postProcess)
|
||||
|
||||
model = QStringListModel()
|
||||
model.setStringList(listItem)
|
||||
completer = QCompleter()
|
||||
completer.setModel(model)
|
||||
self.edit.setCompleter(completer)
|
||||
|
||||
layout = QVBoxLayout()
|
||||
layout.addWidget(self.edit)
|
||||
self.buttonBox = bb = BB(BB.Ok | BB.Cancel, Qt.Horizontal, self)
|
||||
bb.button(BB.Ok).setIcon(newIcon("done"))
|
||||
bb.button(BB.Cancel).setIcon(newIcon("undo"))
|
||||
bb.accepted.connect(self.validate)
|
||||
bb.rejected.connect(self.reject)
|
||||
layout.addWidget(bb)
|
||||
|
||||
# if listItem is not None and len(listItem) > 0:
|
||||
# self.listWidget = QListWidget(self)
|
||||
# for item in listItem:
|
||||
# self.listWidget.addItem(item)
|
||||
# self.listWidget.itemClicked.connect(self.listItemClick)
|
||||
# self.listWidget.itemDoubleClicked.connect(self.listItemDoubleClick)
|
||||
# layout.addWidget(self.listWidget)
|
||||
|
||||
self.setLayout(layout)
|
||||
|
||||
def validate(self):
|
||||
try:
|
||||
if self.edit.text().trimmed():
|
||||
self.accept()
|
||||
except AttributeError:
|
||||
# PyQt5: AttributeError: 'str' object has no attribute 'trimmed'
|
||||
if self.edit.text().strip():
|
||||
self.accept()
|
||||
|
||||
def postProcess(self):
|
||||
try:
|
||||
self.edit.setText(self.edit.text().trimmed())
|
||||
# print(self.edit.text())
|
||||
except AttributeError:
|
||||
# PyQt5: AttributeError: 'str' object has no attribute 'trimmed'
|
||||
self.edit.setText(self.edit.text())
|
||||
print(self.edit.text())
|
||||
|
||||
def popUp(self, text="", move=True):
|
||||
self.edit.setText(text)
|
||||
self.edit.setSelection(0, len(text))
|
||||
self.edit.setFocus(Qt.PopupFocusReason)
|
||||
if move:
|
||||
cursor_pos = QCursor.pos()
|
||||
parent_bottomRight = self.parentWidget().geometry()
|
||||
max_x = (
|
||||
parent_bottomRight.x()
|
||||
+ parent_bottomRight.width()
|
||||
- self.sizeHint().width()
|
||||
)
|
||||
max_y = (
|
||||
parent_bottomRight.y()
|
||||
+ parent_bottomRight.height()
|
||||
- self.sizeHint().height()
|
||||
)
|
||||
max_global = self.parentWidget().mapToGlobal(QPoint(max_x, max_y))
|
||||
if cursor_pos.x() > max_global.x():
|
||||
cursor_pos.setX(max_global.x())
|
||||
if cursor_pos.y() > max_global.y():
|
||||
cursor_pos.setY(max_global.y())
|
||||
self.move(cursor_pos)
|
||||
return self.edit.text() if self.exec_() else None
|
||||
|
||||
def listItemClick(self, tQListWidgetItem):
|
||||
try:
|
||||
text = tQListWidgetItem.text().trimmed()
|
||||
except AttributeError:
|
||||
# PyQt5: AttributeError: 'str' object has no attribute 'trimmed'
|
||||
text = tQListWidgetItem.text().strip()
|
||||
self.edit.setText(text)
|
||||
|
||||
def listItemDoubleClick(self, tQListWidgetItem):
|
||||
self.listItemClick(tQListWidgetItem)
|
||||
self.validate()
|
|
@ -1,60 +0,0 @@
|
|||
# Copyright (c) <2015-Present> Tzutalin
|
||||
# Copyright (C) 2013 MIT, Computer Science and Artificial Intelligence Laboratory. Bryan Russell, Antonio Torralba,
|
||||
# William T. Freeman. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
# associated documentation files (the "Software"), to deal in the Software without restriction, including without
|
||||
# limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
# Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of
|
||||
# the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
# NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
||||
# SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
import pickle
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
||||
class Settings(object):
|
||||
def __init__(self):
|
||||
# Be default, the home will be in the same folder as labelImg
|
||||
home = os.path.expanduser("~")
|
||||
self.data = {}
|
||||
# self.path = os.path.join(home, '.labelImgSettings.pkl')
|
||||
self.path = os.path.join(home, ".autoOCRSettings.pkl")
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
self.data[key] = value
|
||||
|
||||
def __getitem__(self, key):
|
||||
return self.data[key]
|
||||
|
||||
def get(self, key, default=None):
|
||||
if key in self.data:
|
||||
return self.data[key]
|
||||
return default
|
||||
|
||||
def save(self):
|
||||
if self.path:
|
||||
with open(self.path, "wb") as f:
|
||||
pickle.dump(self.data, f, pickle.HIGHEST_PROTOCOL)
|
||||
return True
|
||||
return False
|
||||
|
||||
def load(self):
|
||||
try:
|
||||
if os.path.exists(self.path):
|
||||
with open(self.path, "rb") as f:
|
||||
self.data = pickle.load(f)
|
||||
return True
|
||||
except:
|
||||
print("Loading setting failed")
|
||||
return False
|
||||
|
||||
def reset(self):
|
||||
if os.path.exists(self.path):
|
||||
os.remove(self.path)
|
||||
print("Remove setting pkl file ${0}".format(self.path))
|
||||
self.data = {}
|
||||
self.path = None
|
|
@ -1,280 +0,0 @@
|
|||
# Copyright (c) <2015-Present> Tzutalin
|
||||
# Copyright (C) 2013 MIT, Computer Science and Artificial Intelligence Laboratory. Bryan Russell, Antonio Torralba,
|
||||
# William T. Freeman. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
# associated documentation files (the "Software"), to deal in the Software without restriction, including without
|
||||
# limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
# Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of
|
||||
# the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
# NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
||||
# SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
# !/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
import math
|
||||
import sys
|
||||
|
||||
from PyQt5.QtCore import QPointF
|
||||
from PyQt5.QtGui import QColor, QPen, QPainterPath, QFont
|
||||
from libs.utils import distance
|
||||
from ppocr.utils.logging import get_logger
|
||||
|
||||
DEFAULT_LINE_COLOR = QColor(0, 255, 0, 128)
|
||||
DEFAULT_FILL_COLOR = QColor(255, 0, 0, 128)
|
||||
DEFAULT_SELECT_LINE_COLOR = QColor(255, 255, 255)
|
||||
DEFAULT_SELECT_FILL_COLOR = QColor(0, 128, 255, 155)
|
||||
DEFAULT_VERTEX_FILL_COLOR = QColor(0, 255, 0, 255)
|
||||
DEFAULT_HVERTEX_FILL_COLOR = QColor(255, 0, 0)
|
||||
DEFAULT_LOCK_COLOR = QColor(255, 0, 255)
|
||||
MIN_Y_LABEL = 10
|
||||
|
||||
|
||||
class Shape(object):
|
||||
P_SQUARE, P_ROUND = range(2)
|
||||
|
||||
MOVE_VERTEX, NEAR_VERTEX = range(2)
|
||||
|
||||
# The following class variables influence the drawing
|
||||
# of _all_ shape objects.
|
||||
line_color = DEFAULT_LINE_COLOR
|
||||
fill_color = DEFAULT_FILL_COLOR
|
||||
select_line_color = DEFAULT_SELECT_LINE_COLOR
|
||||
select_fill_color = DEFAULT_SELECT_FILL_COLOR
|
||||
vertex_fill_color = DEFAULT_VERTEX_FILL_COLOR
|
||||
hvertex_fill_color = DEFAULT_HVERTEX_FILL_COLOR
|
||||
point_type = P_ROUND
|
||||
point_size = 8
|
||||
scale = 1.0
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
label=None,
|
||||
line_color=None,
|
||||
difficult=False,
|
||||
key_cls="None",
|
||||
paintLabel=False,
|
||||
paintIdx=False,
|
||||
):
|
||||
self.label = label
|
||||
self.idx = None # bbox order, only for table annotation
|
||||
self.points = []
|
||||
self.fill = False
|
||||
self.selected = False
|
||||
self.difficult = difficult
|
||||
self.key_cls = key_cls
|
||||
self.paintLabel = paintLabel
|
||||
self.paintIdx = paintIdx
|
||||
self.locked = False
|
||||
self.direction = 0
|
||||
self.center = None
|
||||
self.epsilon = 5 # same as canvas
|
||||
self._highlightIndex = None
|
||||
self._highlightMode = self.NEAR_VERTEX
|
||||
self._highlightSettings = {
|
||||
self.NEAR_VERTEX: (4, self.P_ROUND),
|
||||
self.MOVE_VERTEX: (1.5, self.P_SQUARE),
|
||||
}
|
||||
self.fontsize = 8
|
||||
|
||||
self._closed = False
|
||||
|
||||
if line_color is not None:
|
||||
# Override the class line_color attribute
|
||||
# with an object attribute. Currently this
|
||||
# is used for drawing the pending line a different color.
|
||||
self.line_color = line_color
|
||||
|
||||
def rotate(self, theta):
|
||||
for i, p in enumerate(self.points):
|
||||
self.points[i] = self.rotatePoint(p, theta)
|
||||
self.direction -= theta
|
||||
self.direction = self.direction % (2 * math.pi)
|
||||
|
||||
def rotatePoint(self, p, theta):
|
||||
order = p - self.center
|
||||
cosTheta = math.cos(theta)
|
||||
sinTheta = math.sin(theta)
|
||||
pResx = cosTheta * order.x() + sinTheta * order.y()
|
||||
pResy = -sinTheta * order.x() + cosTheta * order.y()
|
||||
pRes = QPointF(self.center.x() + pResx, self.center.y() + pResy)
|
||||
return pRes
|
||||
|
||||
def close(self):
|
||||
try:
|
||||
self.center = QPointF(
|
||||
(self.points[0].x() + self.points[2].x()) / 2,
|
||||
(self.points[0].y() + self.points[2].y()) / 2,
|
||||
)
|
||||
except:
|
||||
self.center = None
|
||||
logger = get_logger()
|
||||
logger.warning("The XY coordinates of QPointF are not detectable!")
|
||||
self._closed = True
|
||||
|
||||
def reachMaxPoints(self):
|
||||
if len(self.points) >= 4:
|
||||
return True
|
||||
return False
|
||||
|
||||
def addPoint(self, point):
|
||||
if self.reachMaxPoints() and self.closeEnough(self.points[0], point):
|
||||
self.close()
|
||||
else:
|
||||
self.points.append(point)
|
||||
|
||||
def closeEnough(self, p1, p2):
|
||||
return distance(p1 - p2) < self.epsilon
|
||||
|
||||
def popPoint(self):
|
||||
if self.points:
|
||||
return self.points.pop()
|
||||
return None
|
||||
|
||||
def isClosed(self):
|
||||
return self._closed
|
||||
|
||||
def setOpen(self):
|
||||
self._closed = False
|
||||
|
||||
def paint(self, painter):
|
||||
if self.points:
|
||||
color = self.select_line_color if self.selected else self.line_color
|
||||
pen = QPen(color)
|
||||
# Try using integer sizes for smoother drawing(?)
|
||||
# pen.setWidth(max(1, int(round(2.0 / self.scale))))
|
||||
painter.setPen(pen)
|
||||
|
||||
line_path = QPainterPath()
|
||||
vrtx_path = QPainterPath()
|
||||
|
||||
line_path.moveTo(self.points[0])
|
||||
# Uncommenting the following line will draw 2 paths
|
||||
# for the 1st vertex, and make it non-filled, which
|
||||
# may be desirable.
|
||||
# self.drawVertex(vrtx_path, 0)
|
||||
|
||||
for i, p in enumerate(self.points):
|
||||
line_path.lineTo(p)
|
||||
self.drawVertex(vrtx_path, i)
|
||||
if self.isClosed():
|
||||
line_path.lineTo(self.points[0])
|
||||
|
||||
painter.drawPath(line_path)
|
||||
painter.drawPath(vrtx_path)
|
||||
painter.fillPath(vrtx_path, self.vertex_fill_color)
|
||||
|
||||
# Draw text at the top-left
|
||||
if self.paintLabel:
|
||||
min_x = sys.maxsize
|
||||
min_y = sys.maxsize
|
||||
for point in self.points:
|
||||
min_x = min(min_x, point.x())
|
||||
min_y = min(min_y, point.y())
|
||||
if min_x != sys.maxsize and min_y != sys.maxsize:
|
||||
font = QFont()
|
||||
font.setPointSize(self.fontsize)
|
||||
font.setBold(True)
|
||||
painter.setFont(font)
|
||||
if self.label is None:
|
||||
self.label = ""
|
||||
if min_y < MIN_Y_LABEL:
|
||||
min_y += MIN_Y_LABEL
|
||||
painter.drawText(min_x, min_y, self.label)
|
||||
|
||||
# Draw number at the top-right
|
||||
if self.paintIdx:
|
||||
min_x = sys.maxsize
|
||||
min_y = sys.maxsize
|
||||
for point in self.points:
|
||||
min_x = min(min_x, point.x())
|
||||
min_y = min(min_y, point.y())
|
||||
if min_x != sys.maxsize and min_y != sys.maxsize:
|
||||
font = QFont()
|
||||
font.setPointSize(self.fontsize)
|
||||
font.setBold(True)
|
||||
painter.setFont(font)
|
||||
text = ""
|
||||
if self.idx != None:
|
||||
text = str(self.idx)
|
||||
if min_y < MIN_Y_LABEL:
|
||||
min_y += MIN_Y_LABEL
|
||||
painter.drawText(min_x, min_y, text)
|
||||
|
||||
if self.fill:
|
||||
color = self.select_fill_color if self.selected else self.fill_color
|
||||
painter.fillPath(line_path, color)
|
||||
|
||||
def drawVertex(self, path, i):
|
||||
d = self.point_size / self.scale
|
||||
shape = self.point_type
|
||||
point = self.points[i]
|
||||
if i == self._highlightIndex:
|
||||
size, shape = self._highlightSettings[self._highlightMode]
|
||||
d *= size
|
||||
if self._highlightIndex is not None:
|
||||
self.vertex_fill_color = self.hvertex_fill_color
|
||||
else:
|
||||
self.vertex_fill_color = Shape.vertex_fill_color
|
||||
if shape == self.P_SQUARE:
|
||||
path.addRect(point.x() - d / 2, point.y() - d / 2, d, d)
|
||||
elif shape == self.P_ROUND:
|
||||
path.addEllipse(point, d / 2.0, d / 2.0)
|
||||
else:
|
||||
assert False, "unsupported vertex shape"
|
||||
|
||||
def nearestVertex(self, point, epsilon):
|
||||
for i, p in enumerate(self.points):
|
||||
if distance(p - point) <= epsilon:
|
||||
return i
|
||||
return None
|
||||
|
||||
def containsPoint(self, point):
|
||||
return self.makePath().contains(point)
|
||||
|
||||
def makePath(self):
|
||||
path = QPainterPath(self.points[0])
|
||||
for p in self.points[1:]:
|
||||
path.lineTo(p)
|
||||
return path
|
||||
|
||||
def boundingRect(self):
|
||||
return self.makePath().boundingRect()
|
||||
|
||||
def moveBy(self, offset):
|
||||
self.points = [p + offset for p in self.points]
|
||||
|
||||
def moveVertexBy(self, i, offset):
|
||||
self.points[i] = self.points[i] + offset
|
||||
|
||||
def highlightVertex(self, i, action):
|
||||
self._highlightIndex = i
|
||||
self._highlightMode = action
|
||||
|
||||
def highlightClear(self):
|
||||
self._highlightIndex = None
|
||||
|
||||
def copy(self):
|
||||
shape = Shape("%s" % self.label)
|
||||
shape.points = [p for p in self.points]
|
||||
shape.center = self.center
|
||||
shape.direction = self.direction
|
||||
shape.fill = self.fill
|
||||
shape.selected = self.selected
|
||||
shape._closed = self._closed
|
||||
if self.line_color != Shape.line_color:
|
||||
shape.line_color = self.line_color
|
||||
if self.fill_color != Shape.fill_color:
|
||||
shape.fill_color = self.fill_color
|
||||
shape.difficult = self.difficult
|
||||
shape.key_cls = self.key_cls
|
||||
return shape
|
||||
|
||||
def __len__(self):
|
||||
return len(self.points)
|
||||
|
||||
def __getitem__(self, key):
|
||||
return self.points[key]
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
self.points[key] = value
|
|
@ -1,95 +0,0 @@
|
|||
# Copyright (c) <2015-Present> Tzutalin
|
||||
# Copyright (C) 2013 MIT, Computer Science and Artificial Intelligence Laboratory. Bryan Russell, Antonio Torralba,
|
||||
# William T. Freeman. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
# associated documentation files (the "Software"), to deal in the Software without restriction, including without
|
||||
# limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
# Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of
|
||||
# the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
# NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
||||
# SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import os
|
||||
import sys
|
||||
import locale
|
||||
from libs.ustr import ustr
|
||||
|
||||
__dir__ = os.path.dirname(os.path.abspath(__file__)) # 获取本程序文件路径
|
||||
__dirpath__ = os.path.abspath(os.path.join(__dir__, "../resources/strings"))
|
||||
|
||||
try:
|
||||
from PyQt5.QtCore import *
|
||||
except ImportError:
|
||||
if sys.version_info.major >= 3:
|
||||
import sip
|
||||
|
||||
sip.setapi("QVariant", 2)
|
||||
from PyQt4.QtCore import *
|
||||
|
||||
|
||||
class StringBundle:
|
||||
__create_key = object()
|
||||
|
||||
def __init__(self, create_key, localeStr):
|
||||
assert (
|
||||
create_key == StringBundle.__create_key
|
||||
), "StringBundle must be created using StringBundle.getBundle"
|
||||
self.idToMessage = {}
|
||||
paths = self.__createLookupFallbackList(localeStr)
|
||||
for path in paths:
|
||||
self.__loadBundle(path)
|
||||
|
||||
@classmethod
|
||||
def getBundle(cls, localeStr=None):
|
||||
if localeStr is None:
|
||||
try:
|
||||
localeStr = (
|
||||
locale.getlocale()[0]
|
||||
if locale.getlocale() and len(locale.getlocale()) > 0
|
||||
else os.getenv("LANG")
|
||||
)
|
||||
except:
|
||||
print("Invalid locale")
|
||||
localeStr = "en"
|
||||
|
||||
return StringBundle(cls.__create_key, localeStr)
|
||||
|
||||
def getString(self, stringId):
|
||||
assert stringId in self.idToMessage, "Missing string id : " + stringId
|
||||
return self.idToMessage[stringId]
|
||||
|
||||
def __createLookupFallbackList(self, localeStr):
|
||||
resultPaths = []
|
||||
basePath = "\strings" if os.name == "nt" else "/strings"
|
||||
resultPaths.append(basePath)
|
||||
if localeStr is not None:
|
||||
# Don't follow standard BCP47. Simple fallback
|
||||
tags = re.split("[^a-zA-Z]", localeStr)
|
||||
for tag in tags:
|
||||
lastPath = resultPaths[-1]
|
||||
resultPaths.append(lastPath + "-" + tag)
|
||||
resultPaths[-1] = __dirpath__ + resultPaths[-1] + ".properties"
|
||||
|
||||
return resultPaths
|
||||
|
||||
def __loadBundle(self, path):
|
||||
PROP_SEPERATOR = "="
|
||||
f = QFile(path)
|
||||
if f.exists():
|
||||
if f.open(QIODevice.ReadOnly | QFile.Text):
|
||||
text = QTextStream(f)
|
||||
text.setCodec("UTF-8")
|
||||
|
||||
while not text.atEnd():
|
||||
line = ustr(text.readLine())
|
||||
key_value = line.split(PROP_SEPERATOR)
|
||||
key = key_value[0].strip()
|
||||
value = PROP_SEPERATOR.join(key_value[1:]).strip().strip('"')
|
||||
self.idToMessage[key] = value
|
||||
|
||||
f.close()
|
|
@ -1,51 +0,0 @@
|
|||
# Copyright (c) <2015-Present> Tzutalin
|
||||
# Copyright (C) 2013 MIT, Computer Science and Artificial Intelligence Laboratory. Bryan Russell, Antonio Torralba,
|
||||
# William T. Freeman. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
# associated documentation files (the "Software"), to deal in the Software without restriction, including without
|
||||
# limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
# Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of
|
||||
# the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
# NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
||||
# SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
try:
|
||||
from PyQt5.QtGui import *
|
||||
from PyQt5.QtCore import *
|
||||
from PyQt5.QtWidgets import *
|
||||
except ImportError:
|
||||
from PyQt4.QtGui import *
|
||||
from PyQt4.QtCore import *
|
||||
|
||||
|
||||
class ToolBar(QToolBar):
|
||||
def __init__(self, title):
|
||||
super(ToolBar, self).__init__(title)
|
||||
layout = self.layout()
|
||||
m = (0, 0, 0, 0)
|
||||
layout.setSpacing(0)
|
||||
layout.setContentsMargins(*m)
|
||||
self.setContentsMargins(*m)
|
||||
self.setWindowFlags(self.windowFlags() | Qt.FramelessWindowHint)
|
||||
|
||||
def addAction(self, action):
|
||||
if isinstance(action, QWidgetAction):
|
||||
return super(ToolBar, self).addAction(action)
|
||||
btn = ToolButton()
|
||||
btn.setDefaultAction(action)
|
||||
btn.setToolButtonStyle(self.toolButtonStyle())
|
||||
self.addWidget(btn)
|
||||
|
||||
|
||||
class ToolButton(QToolButton):
|
||||
"""ToolBar companion class which ensures all buttons have the same size."""
|
||||
|
||||
minSize = (60, 60)
|
||||
|
||||
def minimumSizeHint(self):
|
||||
ms = super(ToolButton, self).minimumSizeHint()
|
||||
w1, h1 = ms.width(), ms.height()
|
||||
w2, h2 = self.minSize
|
||||
ToolButton.minSize = max(w1, w2), max(h1, h2)
|
||||
return QSize(*ToolButton.minSize)
|
|
@ -1,48 +0,0 @@
|
|||
# -*- encoding: utf-8 -*-
|
||||
|
||||
from PyQt5.QtCore import Qt, QSize
|
||||
from PyQt5 import QtWidgets
|
||||
|
||||
|
||||
class EscapableQListWidget(QtWidgets.QListWidget):
|
||||
def keyPressEvent(self, event):
|
||||
super(EscapableQListWidget, self).keyPressEvent(event)
|
||||
if event.key() == Qt.Key_Escape:
|
||||
self.clearSelection()
|
||||
|
||||
|
||||
class UniqueLabelQListWidget(EscapableQListWidget):
|
||||
def mousePressEvent(self, event):
|
||||
super(UniqueLabelQListWidget, self).mousePressEvent(event)
|
||||
if not self.indexAt(event.pos()).isValid():
|
||||
self.clearSelection()
|
||||
|
||||
def findItemsByLabel(self, label, get_row=False):
|
||||
items = []
|
||||
for row in range(self.count()):
|
||||
item = self.item(row)
|
||||
if item.data(Qt.UserRole) == label:
|
||||
items.append(item)
|
||||
if get_row:
|
||||
return row
|
||||
return items
|
||||
|
||||
def createItemFromLabel(self, label):
|
||||
item = QtWidgets.QListWidgetItem()
|
||||
item.setData(Qt.UserRole, label)
|
||||
return item
|
||||
|
||||
def setItemLabel(self, item, label, color=None):
|
||||
qlabel = QtWidgets.QLabel()
|
||||
if color is None:
|
||||
qlabel.setText(f"{label}")
|
||||
else:
|
||||
qlabel.setText(
|
||||
'<font color="#{:02x}{:02x}{:02x}">●</font> {} '.format(*color, label)
|
||||
)
|
||||
qlabel.setAlignment(Qt.AlignBottom)
|
||||
|
||||
# item.setSizeHint(qlabel.sizeHint())
|
||||
item.setSizeHint(QSize(25, 25))
|
||||
|
||||
self.setItemWidget(item, qlabel)
|
|
@ -1,31 +0,0 @@
|
|||
# Copyright (c) <2015-Present> Tzutalin
|
||||
# Copyright (C) 2013 MIT, Computer Science and Artificial Intelligence Laboratory. Bryan Russell, Antonio Torralba,
|
||||
# William T. Freeman. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
# associated documentation files (the "Software"), to deal in the Software without restriction, including without
|
||||
# limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
# Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of
|
||||
# the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
# NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
||||
# SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
import sys
|
||||
from libs.constants import DEFAULT_ENCODING
|
||||
|
||||
|
||||
def ustr(x):
|
||||
"""py2/py3 unicode helper"""
|
||||
|
||||
if sys.version_info < (3, 0, 0):
|
||||
from PyQt4.QtCore import QString
|
||||
|
||||
if type(x) == str:
|
||||
return x.decode(DEFAULT_ENCODING)
|
||||
if type(x) == QString:
|
||||
# https://blog.csdn.net/friendan/article/details/51088476
|
||||
# https://blog.csdn.net/xxm524/article/details/74937308
|
||||
return unicode(x.toUtf8(), DEFAULT_ENCODING, "ignore")
|
||||
return x
|
||||
else:
|
||||
return x
|
|
@ -1,355 +0,0 @@
|
|||
# Copyright (c) <2015-Present> Tzutalin
|
||||
# Copyright (C) 2013 MIT, Computer Science and Artificial Intelligence Laboratory. Bryan Russell, Antonio Torralba,
|
||||
# William T. Freeman. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
# associated documentation files (the "Software"), to deal in the Software without restriction, including without
|
||||
# limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
# Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of
|
||||
# the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
# NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
||||
# SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
import hashlib
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
from math import sqrt
|
||||
|
||||
import cv2
|
||||
import numpy as np
|
||||
from PyQt5.QtCore import QRegExp, QT_VERSION_STR
|
||||
from PyQt5.QtGui import QIcon, QRegExpValidator, QColor
|
||||
from PyQt5.QtWidgets import QPushButton, QAction, QMenu
|
||||
from libs.ustr import ustr
|
||||
|
||||
__dir__ = os.path.dirname(os.path.abspath(__file__)) # 获取本程序文件路径
|
||||
__iconpath__ = os.path.abspath(os.path.join(__dir__, "../resources/icons"))
|
||||
|
||||
|
||||
def newIcon(icon, iconSize=None):
|
||||
if iconSize is not None:
|
||||
return QIcon(
|
||||
QIcon(__iconpath__ + "/" + icon + ".png").pixmap(iconSize, iconSize)
|
||||
)
|
||||
else:
|
||||
return QIcon(__iconpath__ + "/" + icon + ".png")
|
||||
|
||||
|
||||
def newButton(text, icon=None, slot=None):
|
||||
b = QPushButton(text)
|
||||
if icon is not None:
|
||||
b.setIcon(newIcon(icon))
|
||||
if slot is not None:
|
||||
b.clicked.connect(slot)
|
||||
return b
|
||||
|
||||
|
||||
def newAction(
|
||||
parent,
|
||||
text,
|
||||
slot=None,
|
||||
shortcut=None,
|
||||
icon=None,
|
||||
tip=None,
|
||||
checkable=False,
|
||||
enabled=True,
|
||||
iconSize=None,
|
||||
):
|
||||
"""Create a new action and assign callbacks, shortcuts, etc."""
|
||||
a = QAction(text, parent)
|
||||
if icon is not None:
|
||||
if iconSize is not None:
|
||||
a.setIcon(newIcon(icon, iconSize))
|
||||
else:
|
||||
a.setIcon(newIcon(icon))
|
||||
if shortcut is not None:
|
||||
if isinstance(shortcut, (list, tuple)):
|
||||
a.setShortcuts(shortcut)
|
||||
else:
|
||||
a.setShortcut(shortcut)
|
||||
if tip is not None:
|
||||
a.setToolTip(tip)
|
||||
a.setStatusTip(tip)
|
||||
if slot is not None:
|
||||
a.triggered.connect(slot)
|
||||
if checkable:
|
||||
a.setCheckable(True)
|
||||
a.setEnabled(enabled)
|
||||
return a
|
||||
|
||||
|
||||
def addActions(widget, actions):
|
||||
for action in actions:
|
||||
if action is None:
|
||||
widget.addSeparator()
|
||||
elif isinstance(action, QMenu):
|
||||
widget.addMenu(action)
|
||||
else:
|
||||
widget.addAction(action)
|
||||
|
||||
|
||||
def labelValidator():
|
||||
return QRegExpValidator(QRegExp(r"^[^ \t].+"), None)
|
||||
|
||||
|
||||
class struct(object):
|
||||
def __init__(self, **kwargs):
|
||||
self.__dict__.update(kwargs)
|
||||
|
||||
|
||||
def distance(p):
|
||||
return sqrt(p.x() * p.x() + p.y() * p.y())
|
||||
|
||||
|
||||
def fmtShortcut(text):
|
||||
mod, key = text.split("+", 1)
|
||||
return "<b>%s</b>+<b>%s</b>" % (mod, key)
|
||||
|
||||
|
||||
def generateColorByText(text):
|
||||
s = ustr(text)
|
||||
hashCode = int(hashlib.sha256(s.encode("utf-8")).hexdigest(), 16)
|
||||
r = int((hashCode / 255) % 255)
|
||||
g = int((hashCode / 65025) % 255)
|
||||
b = int((hashCode / 16581375) % 255)
|
||||
return QColor(r, g, b, 100)
|
||||
|
||||
|
||||
def have_qstring():
|
||||
"""p3/qt5 get rid of QString wrapper as py3 has native unicode str type"""
|
||||
return not (sys.version_info.major >= 3 or QT_VERSION_STR.startswith("5."))
|
||||
|
||||
|
||||
def natural_sort(list, key=lambda s: s):
|
||||
"""
|
||||
Sort the list into natural alphanumeric order.
|
||||
"""
|
||||
|
||||
def get_alphanum_key_func(key):
|
||||
convert = lambda text: int(text) if text.isdigit() else text
|
||||
return lambda s: [convert(c) for c in re.split("([0-9]+)", key(s))]
|
||||
|
||||
sort_key = get_alphanum_key_func(key)
|
||||
list.sort(key=sort_key)
|
||||
|
||||
|
||||
def get_rotate_crop_image(img, points):
|
||||
# Use Green's theory to judge clockwise or counterclockwise
|
||||
# author: biyanhua
|
||||
d = 0.0
|
||||
for index in range(-1, 3):
|
||||
d += (
|
||||
-0.5
|
||||
* (points[index + 1][1] + points[index][1])
|
||||
* (points[index + 1][0] - points[index][0])
|
||||
)
|
||||
if d < 0: # counterclockwise
|
||||
tmp = np.array(points)
|
||||
points[1], points[3] = tmp[3], tmp[1]
|
||||
|
||||
try:
|
||||
img_crop_width = int(
|
||||
max(
|
||||
np.linalg.norm(points[0] - points[1]),
|
||||
np.linalg.norm(points[2] - points[3]),
|
||||
)
|
||||
)
|
||||
img_crop_height = int(
|
||||
max(
|
||||
np.linalg.norm(points[0] - points[3]),
|
||||
np.linalg.norm(points[1] - points[2]),
|
||||
)
|
||||
)
|
||||
pts_std = np.float32(
|
||||
[
|
||||
[0, 0],
|
||||
[img_crop_width, 0],
|
||||
[img_crop_width, img_crop_height],
|
||||
[0, img_crop_height],
|
||||
]
|
||||
)
|
||||
M = cv2.getPerspectiveTransform(points, pts_std)
|
||||
dst_img = cv2.warpPerspective(
|
||||
img,
|
||||
M,
|
||||
(img_crop_width, img_crop_height),
|
||||
borderMode=cv2.BORDER_REPLICATE,
|
||||
flags=cv2.INTER_CUBIC,
|
||||
)
|
||||
dst_img_height, dst_img_width = dst_img.shape[0:2]
|
||||
if dst_img_height * 1.0 / dst_img_width >= 1.5:
|
||||
dst_img = np.rot90(dst_img)
|
||||
return dst_img
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
|
||||
def boxPad(box, imgShape, pad: int) -> np.array:
|
||||
"""
|
||||
Pad a box with [pad] pixels on each side.
|
||||
"""
|
||||
box = np.array(box, dtype=np.int32)
|
||||
box[0][0], box[0][1] = box[0][0] - pad, box[0][1] - pad
|
||||
box[1][0], box[1][1] = box[1][0] + pad, box[1][1] - pad
|
||||
box[2][0], box[2][1] = box[2][0] + pad, box[2][1] + pad
|
||||
box[3][0], box[3][1] = box[3][0] - pad, box[3][1] + pad
|
||||
h, w, _ = imgShape
|
||||
box[:, 0] = np.clip(box[:, 0], 0, w)
|
||||
box[:, 1] = np.clip(box[:, 1], 0, h)
|
||||
return box
|
||||
|
||||
|
||||
def expand_list(merged, html_list):
|
||||
"""
|
||||
Fill blanks according to merged cells
|
||||
"""
|
||||
sr, er, sc, ec = merged
|
||||
for i in range(sr, er):
|
||||
for j in range(sc, ec):
|
||||
html_list[i][j] = None
|
||||
html_list[sr][sc] = ""
|
||||
if ec - sc > 1:
|
||||
html_list[sr][sc] += " colspan={}".format(ec - sc)
|
||||
if er - sr > 1:
|
||||
html_list[sr][sc] += " rowspan={}".format(er - sr)
|
||||
return html_list
|
||||
|
||||
|
||||
def convert_token(html_list):
|
||||
"""
|
||||
Convert raw html to label format
|
||||
"""
|
||||
token_list = ["<tbody>"]
|
||||
# final html list:
|
||||
for row in html_list:
|
||||
token_list.append("<tr>")
|
||||
for col in row:
|
||||
if col == None:
|
||||
continue
|
||||
elif col == "td":
|
||||
token_list.extend(["<td>", "</td>"])
|
||||
else:
|
||||
token_list.append("<td")
|
||||
if "colspan" in col:
|
||||
_, n = col.split("colspan=")
|
||||
token_list.append(' colspan="{}"'.format(n[0]))
|
||||
if "rowspan" in col:
|
||||
_, n = col.split("rowspan=")
|
||||
token_list.append(' rowspan="{}"'.format(n[0]))
|
||||
token_list.extend([">", "</td>"])
|
||||
token_list.append("</tr>")
|
||||
token_list.append("</tbody>")
|
||||
|
||||
return token_list
|
||||
|
||||
|
||||
def rebuild_html_from_ppstructure_label(label_info):
|
||||
from html import escape
|
||||
|
||||
html_code = label_info["html"]["structure"]["tokens"].copy()
|
||||
to_insert = [i for i, tag in enumerate(html_code) if tag in ("<td>", ">")]
|
||||
for i, cell in zip(to_insert[::-1], label_info["html"]["cells"][::-1]):
|
||||
if cell["tokens"]:
|
||||
cell = [
|
||||
escape(token) if len(token) == 1 else token for token in cell["tokens"]
|
||||
]
|
||||
cell = "".join(cell)
|
||||
html_code.insert(i + 1, cell)
|
||||
html_code = "".join(html_code)
|
||||
html_code = "<html><body><table>{}</table></body></html>".format(html_code)
|
||||
return html_code
|
||||
|
||||
|
||||
def stepsInfo(lang="en"):
|
||||
if lang == "ch":
|
||||
msg = (
|
||||
"1. 安装与运行:使用上述命令安装与运行程序。\n"
|
||||
"2. 打开文件夹:在菜单栏点击 “文件” - 打开目录 选择待标记图片的文件夹.\n"
|
||||
"3. 自动标注:点击 ”自动标注“,使用PPOCR超轻量模型对图片文件名前图片状态为 “X” 的图片进行自动标注。\n"
|
||||
"4. 手动标注:点击 “矩形标注”(推荐直接在英文模式下点击键盘中的 “W”),用户可对当前图片中模型未检出的部分进行手动"
|
||||
"绘制标记框。点击键盘P,则使用四点标注模式(或点击“编辑” - “四点标注”),用户依次点击4个点后,双击左键表示标注完成。\n"
|
||||
"5. 标记框绘制完成后,用户点击 “确认”,检测框会先被预分配一个 “待识别” 标签。\n"
|
||||
"6. 重新识别:将图片中的所有检测画绘制/调整完成后,点击 “重新识别”,PPOCR模型会对当前图片中的**所有检测框**重新识别。\n"
|
||||
"7. 内容更改:双击识别结果,对不准确的识别结果进行手动更改。\n"
|
||||
"8. 保存:点击 “保存”,图片状态切换为 “√”,跳转至下一张。\n"
|
||||
"9. 删除:点击 “删除图像”,图片将会被删除至回收站。\n"
|
||||
"10. 标注结果:关闭应用程序或切换文件路径后,手动保存过的标签将会被存放在所打开图片文件夹下的"
|
||||
"*Label.txt*中。在菜单栏点击 “PaddleOCR” - 保存识别结果后,会将此类图片的识别训练数据保存在*crop_img*文件夹下,"
|
||||
"识别标签保存在*rec_gt.txt*中。\n"
|
||||
)
|
||||
|
||||
else:
|
||||
msg = (
|
||||
"1. Build and launch using the instructions above.\n"
|
||||
"2. Click 'Open Dir' in Menu/File to select the folder of the picture.\n"
|
||||
"3. Click 'Auto recognition', use PPOCR model to automatically annotate images which marked with 'X' before the file name."
|
||||
"4. Create Box:\n"
|
||||
"4.1 Click 'Create RectBox' or press 'W' in English keyboard mode to draw a new rectangle detection box. Click and release left mouse to select a region to annotate the text area.\n"
|
||||
"4.2 Press 'P' to enter four-point labeling mode which enables you to create any four-point shape by clicking four points with the left mouse button in succession and DOUBLE CLICK the left mouse as the signal of labeling completion.\n"
|
||||
"5. After the marking frame is drawn, the user clicks 'OK', and the detection frame will be pre-assigned a TEMPORARY label.\n"
|
||||
"6. Click re-Recognition, model will rewrite ALL recognition results in ALL detection box.\n"
|
||||
"7. Double click the result in 'recognition result' list to manually change inaccurate recognition results.\n"
|
||||
"8. Click 'Save', the image status will switch to '√',then the program automatically jump to the next.\n"
|
||||
"9. Click 'Delete Image' and the image will be deleted to the recycle bin.\n"
|
||||
"10. Labeling result: After closing the application or switching the file path, the manually saved label will be stored in *Label.txt* under the opened picture folder.\n"
|
||||
" Click PaddleOCR-Save Recognition Results in the menu bar, the recognition training data of such pictures will be saved in the *crop_img* folder, and the recognition label will be saved in *rec_gt.txt*.\n"
|
||||
)
|
||||
|
||||
return msg
|
||||
|
||||
|
||||
def keysInfo(lang="en"):
|
||||
if lang == "ch":
|
||||
msg = (
|
||||
"快捷键\t\t\t说明\n"
|
||||
"———————————————————————\n"
|
||||
"Ctrl + shift + R\t\t对当前图片的所有标记重新识别\n"
|
||||
"W\t\t\t新建矩形框\n"
|
||||
"Q\t\t\t新建四点框\n"
|
||||
"Ctrl + E\t\t编辑所选框标签\n"
|
||||
"Ctrl + R\t\t重新识别所选标记\n"
|
||||
"Ctrl + C\t\t复制并粘贴选中的标记框\n"
|
||||
"Ctrl + 鼠标左键\t\t多选标记框\n"
|
||||
"Backspace\t\t删除所选框\n"
|
||||
"Ctrl + V\t\t确认本张图片标记\n"
|
||||
"Ctrl + Shift + d\t删除本张图片\n"
|
||||
"D\t\t\t下一张图片\n"
|
||||
"A\t\t\t上一张图片\n"
|
||||
"Ctrl++\t\t\t缩小\n"
|
||||
"Ctrl--\t\t\t放大\n"
|
||||
"↑→↓←\t\t\t移动标记框\n"
|
||||
"———————————————————————\n"
|
||||
"注:Mac用户Command键替换上述Ctrl键"
|
||||
)
|
||||
|
||||
else:
|
||||
msg = (
|
||||
"Shortcut Keys\t\tDescription\n"
|
||||
"———————————————————————\n"
|
||||
"Ctrl + shift + R\t\tRe-recognize all the labels\n"
|
||||
"\t\t\tof the current image\n"
|
||||
"\n"
|
||||
"W\t\t\tCreate a rect box\n"
|
||||
"Q\t\t\tCreate a four-points box\n"
|
||||
"Ctrl + E\t\tEdit label of the selected box\n"
|
||||
"Ctrl + R\t\tRe-recognize the selected box\n"
|
||||
"Ctrl + C\t\tCopy and paste the selected\n"
|
||||
"\t\t\tbox\n"
|
||||
"\n"
|
||||
"Ctrl + Left Mouse\tMulti select the label\n"
|
||||
"Button\t\t\tbox\n"
|
||||
"\n"
|
||||
"Backspace\t\tDelete the selected box\n"
|
||||
"Ctrl + V\t\tCheck image\n"
|
||||
"Ctrl + Shift + d\tDelete image\n"
|
||||
"D\t\t\tNext image\n"
|
||||
"A\t\t\tPrevious image\n"
|
||||
"Ctrl++\t\t\tZoom in\n"
|
||||
"Ctrl--\t\t\tZoom out\n"
|
||||
"↑→↓←\t\t\tMove selected box"
|
||||
"———————————————————————\n"
|
||||
"Notice:For Mac users, use the 'Command' key instead of the 'Ctrl' key"
|
||||
)
|
||||
|
||||
return msg
|
|
@ -1,37 +0,0 @@
|
|||
# Copyright (c) <2015-Present> Tzutalin
|
||||
# Copyright (C) 2013 MIT, Computer Science and Artificial Intelligence Laboratory. Bryan Russell, Antonio Torralba,
|
||||
# William T. Freeman. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
# associated documentation files (the "Software"), to deal in the Software without restriction, including without
|
||||
# limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
# Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of
|
||||
# the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
# NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
||||
# SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
try:
|
||||
from PyQt5.QtGui import *
|
||||
from PyQt5.QtCore import *
|
||||
from PyQt5.QtWidgets import *
|
||||
except ImportError:
|
||||
from PyQt4.QtGui import *
|
||||
from PyQt4.QtCore import *
|
||||
|
||||
|
||||
class ZoomWidget(QSpinBox):
|
||||
def __init__(self, value=100):
|
||||
super(ZoomWidget, self).__init__()
|
||||
self.setButtonSymbols(QAbstractSpinBox.NoButtons)
|
||||
self.setRange(1, 500)
|
||||
self.setSuffix(" %")
|
||||
self.setValue(value)
|
||||
self.setToolTip("Zoom Level")
|
||||
self.setStatusTip(self.toolTip())
|
||||
self.setAlignment(Qt.AlignCenter)
|
||||
|
||||
def minimumSizeHint(self):
|
||||
height = super(ZoomWidget, self).minimumSizeHint().height()
|
||||
fm = QFontMetrics(self.font())
|
||||
width = fm.width(str(self.maximum()))
|
||||
return QSize(width, height)
|
|
@ -1,3 +0,0 @@
|
|||
pyqt5
|
||||
paddleocr
|
||||
xlrd==1.2.0
|
|
@ -1,41 +0,0 @@
|
|||
<!DOCTYPE RCC><RCC version="1.0">
|
||||
<qresource>
|
||||
|
||||
<file alias="help">resources/icons/help.png</file>
|
||||
<file alias="app">resources/icons/app.png</file>
|
||||
<file alias="Auto">resources/icons/Auto.png</file>
|
||||
<file alias="reRec">resources/icons/reRec.png</file>
|
||||
<file alias="expert">resources/icons/expert2.png</file>
|
||||
<file alias="done">resources/icons/done.png</file>
|
||||
<file alias="file">resources/icons/file.png</file>
|
||||
<file alias="labels">resources/icons/labels.png</file>
|
||||
<file alias="new">resources/icons/objects.png</file>
|
||||
<file alias="close">resources/icons/close.png</file>
|
||||
<file alias="fit-width">resources/icons/fit-width.png</file>
|
||||
<file alias="fit-window">resources/icons/fit-window.png</file>
|
||||
<file alias="undo">resources/icons/undo.png</file>
|
||||
<file alias="hide">resources/icons/eye.png</file>
|
||||
<file alias="quit">resources/icons/quit.png</file>
|
||||
<file alias="copy">resources/icons/copy.png</file>
|
||||
<file alias="edit">resources/icons/edit.png</file>
|
||||
<file alias="rotateLeft">resources/icons/rotateLeft.png</file>
|
||||
<file alias="rotateRight">resources/icons/rotateRight.png</file>
|
||||
<file alias="open">resources/icons/open.png</file>
|
||||
<file alias="save">resources/icons/save.png</file>
|
||||
<file alias="format_voc">resources/icons/format_voc.png</file>
|
||||
<file alias="format_yolo">resources/icons/format_yolo.png</file>
|
||||
<file alias="save-as">resources/icons/save-as.png</file>
|
||||
<file alias="color">resources/icons/color.png</file>
|
||||
<file alias="color_line">resources/icons/color_line.png</file>
|
||||
<file alias="zoom">resources/icons/zoom.png</file>
|
||||
<file alias="zoom-in">resources/icons/zoom-in.png</file>
|
||||
<file alias="zoom-out">resources/icons/zoom-out.png</file>
|
||||
<file alias="delete">resources/icons/cancel.png</file>
|
||||
<file alias="next">resources/icons/next.png</file>
|
||||
<file alias="prev">resources/icons/prev.png</file>
|
||||
<file alias="resetall">resources/icons/resetall.png</file>
|
||||
<file alias="verify">resources/icons/verify.png</file>
|
||||
<file alias="strings">resources/strings/strings-en.properties</file>
|
||||
<file alias="strings-zh-CN">resources/strings/strings-zh-CN.properties</file>
|
||||
</qresource>
|
||||
</RCC>
|
Before Width: | Height: | Size: 471 B |
Before Width: | Height: | Size: 58 KiB |
|
@ -1,27 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="200px" height="200px" viewBox="0 0 200 200" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>APPicon备份 3@2x</title>
|
||||
<defs>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
|
||||
<stop stop-color="#A5ACFF" offset="0%"></stop>
|
||||
<stop stop-color="#545DFF" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="APPicon备份-3" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="编组-3备份-2" fill="url(#linearGradient-1)">
|
||||
<rect id="矩形" x="0" y="0" width="200" height="200" rx="4"></rect>
|
||||
</g>
|
||||
<g id="编组-4备份" transform="translate(11.000000, 11.000000)">
|
||||
<polyline id="路径" stroke="#FFFFFF" stroke-width="6" stroke-linecap="round" stroke-linejoin="round" points="104 167 11 167 11 11 167 11 167 96.7728865"></polyline>
|
||||
<circle id="椭圆形" fill="#FFFFFF" cx="167" cy="11" r="11"></circle>
|
||||
<circle id="椭圆形备份-8" fill="#FFFFFF" cx="11" cy="11" r="11"></circle>
|
||||
<circle id="椭圆形备份-9" fill="#FFFFFF" cx="11" cy="167" r="11"></circle>
|
||||
</g>
|
||||
<path d="M85.9991492,141 L69,141 L69,60 L97.061099,60.0005168 C106.622339,60.0180588 113.008403,60.4807625 115.775763,61.1684309 C120.478388,62.336394 124.240393,64.9067781 127.297375,69.1122872 C130.353887,73.08404 132,78.4580969 132,84.7663606 C132,89.6731387 131.059499,93.8786478 129.413268,97.1497163 C127.767626,100.420785 125.416373,103.224458 122.594751,105.09369 C119.773129,106.962805 116.951625,108.364641 114.130121,108.83192 C110.367998,109.766594 104.724872,110 97.4355156,110 L97.4355156,110 L85.999,110 L85.9991492,141 Z M86,74.2965717 L85.9299926,74.2965717 L85.929,96.849 L95.7229134,96.8497738 C101.895297,96.8497738 106.289281,96.4080944 108.473591,95.739226 L108.655396,95.681343 C110.771288,94.9806587 112.417401,93.5787054 113.828271,91.7095902 C115.239023,89.840475 115.709274,87.7373697 115.709274,85.4009757 C115.709274,82.3637805 114.768772,80.0273866 113.122542,78.1581545 C111.476782,76.2890393 109.125646,75.1206084 106.538915,74.6533297 C104.879206,74.2409217 101.572085,74.1924031 96.7786667,74.186695 L95.8002135,74.1860291 C95.4674884,74.1859339 95.1282054,74.1859339 94.7824121,74.1859339 L86,74.185 L86,74.2965717 Z" id="形状结合" fill="#FFFFFF"></path>
|
||||
<g id="编组" transform="translate(158.000000, 153.000000) rotate(65.000000) translate(-158.000000, -153.000000) translate(126.000000, 113.000000)">
|
||||
<path d="M32,8 C14.326888,8 0,22.326888 0,40 C0,49.0801087 3.78188139,57.2769117 9.85641113,63.1011759 M32,72 C49.673112,72 64,57.673112 64,40 C64,30.9865538 60.2734449,22.8434911 54.2770078,17.0274853" id="形状备份-2" stroke="#FFFFFF" stroke-width="5" stroke-linecap="round"></path>
|
||||
<polygon id="三角形备份-3" fill="#FFFFFF" transform="translate(38.000000, 8.000000) scale(-1, 1) rotate(-90.000000) translate(-38.000000, -8.000000) " points="38 2 46 14 30 14"></polygon>
|
||||
<polygon id="三角形备份-4" fill="#FFFFFF" transform="translate(26.000000, 72.000000) rotate(-90.000000) translate(-26.000000, -72.000000) " points="26 66 34 78 18 78"></polygon>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 646 B |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 2.1 KiB |
|
@ -1,400 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
|
||||
<svg
|
||||
width="48pt"
|
||||
height="48pt"
|
||||
viewBox="0 0 256 256"
|
||||
style="overflow:visible;enable-background:new 0 0 256 256"
|
||||
xml:space="preserve"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xap="http://ns.adobe.com/xap/1.0/"
|
||||
xmlns:xapGImg="http://ns.adobe.com/xap/1.0/g/img/"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:xml="http://www.w3.org/XML/1998/namespace"
|
||||
xmlns:xapMM="http://ns.adobe.com/xap/1.0/mm/"
|
||||
xmlns:pdf="http://ns.adobe.com/pdf/1.3/"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
|
||||
xmlns:x="adobe:ns:meta/"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
id="svg548"
|
||||
sodipodi:version="0.32"
|
||||
sodipodi:docname="/home/david/Desktop/action/button_ok.svg"
|
||||
sodipodi:docbase="/home/david/Desktop/action/">
|
||||
<defs
|
||||
id="defs584">
|
||||
<linearGradient
|
||||
id="XMLID_5_"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="127.9536"
|
||||
y1="47.3267"
|
||||
x2="127.9536"
|
||||
y2="212.9885">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#009900"
|
||||
id="stop556" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#334966"
|
||||
id="stop557" />
|
||||
<a:midPointStop
|
||||
offset="0"
|
||||
style="stop-color:#009900"
|
||||
id="midPointStop558" />
|
||||
<a:midPointStop
|
||||
offset="0.5"
|
||||
style="stop-color:#009900"
|
||||
id="midPointStop559" />
|
||||
<a:midPointStop
|
||||
offset="1"
|
||||
style="stop-color:#334966"
|
||||
id="midPointStop560" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="XMLID_6_"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="127.9536"
|
||||
y1="77.2075"
|
||||
x2="127.9536"
|
||||
y2="307.6057">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#33CC33"
|
||||
id="stop563" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#336666"
|
||||
id="stop564" />
|
||||
<a:midPointStop
|
||||
offset="0"
|
||||
style="stop-color:#33CC33"
|
||||
id="midPointStop565" />
|
||||
<a:midPointStop
|
||||
offset="0.5"
|
||||
style="stop-color:#33CC33"
|
||||
id="midPointStop566" />
|
||||
<a:midPointStop
|
||||
offset="1"
|
||||
style="stop-color:#336666"
|
||||
id="midPointStop567" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="XMLID_7_"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="127.9536"
|
||||
y1="77.3672"
|
||||
x2="127.9536"
|
||||
y2="307.3626">
|
||||
<stop
|
||||
offset="0.0056"
|
||||
style="stop-color:#CCFF66"
|
||||
id="stop570" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#009900"
|
||||
id="stop571" />
|
||||
<a:midPointStop
|
||||
offset="0.0056"
|
||||
style="stop-color:#CCFF66"
|
||||
id="midPointStop572" />
|
||||
<a:midPointStop
|
||||
offset="0.5"
|
||||
style="stop-color:#CCFF66"
|
||||
id="midPointStop573" />
|
||||
<a:midPointStop
|
||||
offset="1"
|
||||
style="stop-color:#009900"
|
||||
id="midPointStop574" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
id="XMLID_8_"
|
||||
cx="54.2729"
|
||||
cy="89.3477"
|
||||
r="120.8132"
|
||||
fx="54.2729"
|
||||
fy="89.3477"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop
|
||||
offset="0.000000"
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
id="stop577" />
|
||||
<stop
|
||||
offset="1.000000"
|
||||
style="stop-color:#92ff00;stop-opacity:1;"
|
||||
id="stop578" />
|
||||
<a:midPointStop
|
||||
offset="0"
|
||||
style="stop-color:#FFFFFF"
|
||||
id="midPointStop579" />
|
||||
<a:midPointStop
|
||||
offset="0.5"
|
||||
style="stop-color:#FFFFFF"
|
||||
id="midPointStop580" />
|
||||
<a:midPointStop
|
||||
offset="1"
|
||||
style="stop-color:#000000"
|
||||
id="midPointStop581" />
|
||||
</radialGradient>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base" />
|
||||
<metadata
|
||||
id="metadata549">
|
||||
<xpacket>begin='' id='W5M0MpCehiHzreSzNTczkc9d' </xpacket>
|
||||
<x:xmpmeta
|
||||
x:xmptk="XMP toolkit 3.0-29, framework 1.6">
|
||||
<rdf:RDF>
|
||||
<rdf:Description
|
||||
rdf:about="uuid:609bc623-b01c-476b-9349-300763160df1">
|
||||
<pdf:Producer>
|
||||
Adobe PDF library 5.00</pdf:Producer>
|
||||
</rdf:Description>
|
||||
<rdf:Description
|
||||
rdf:about="uuid:609bc623-b01c-476b-9349-300763160df1" />
|
||||
<rdf:Description
|
||||
rdf:about="uuid:609bc623-b01c-476b-9349-300763160df1" />
|
||||
<rdf:Description
|
||||
rdf:about="uuid:609bc623-b01c-476b-9349-300763160df1">
|
||||
<xap:CreateDate>
|
||||
2003-12-22T22:34:35+02:00</xap:CreateDate>
|
||||
<xap:ModifyDate>
|
||||
2004-04-17T21:25:50Z</xap:ModifyDate>
|
||||
<xap:CreatorTool>
|
||||
Adobe Illustrator 10.0</xap:CreatorTool>
|
||||
<xap:MetadataDate>
|
||||
2004-01-19T17:51:02+01:00</xap:MetadataDate>
|
||||
<xap:Thumbnails>
|
||||
<rdf:Alt>
|
||||
<rdf:li
|
||||
rdf:parseType="Resource">
|
||||
<xapGImg:format>
|
||||
JPEG</xapGImg:format>
|
||||
<xapGImg:width>
|
||||
256</xapGImg:width>
|
||||
<xapGImg:height>
|
||||
256</xapGImg:height>
|
||||
<xapGImg:image>
|
||||
/9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA
|
||||
AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK
|
||||
DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f
|
||||
Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgBAAEAAwER
|
||||
AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA
|
||||
AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB
|
||||
UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE
|
||||
1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ
|
||||
qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy
|
||||
obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp
|
||||
0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo
|
||||
+DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q7FXYq7FXYq7FXYq7
|
||||
FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7F
|
||||
XYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FX
|
||||
Yq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXY
|
||||
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</xapGImg:image>
|
||||
</rdf:li>
|
||||
</rdf:Alt>
|
||||
</xap:Thumbnails>
|
||||
</rdf:Description>
|
||||
<rdf:Description
|
||||
rdf:about="uuid:609bc623-b01c-476b-9349-300763160df1">
|
||||
<xapMM:DocumentID>
|
||||
uuid:4b4d592f-95b8-4bcd-a892-74a536c5e52f</xapMM:DocumentID>
|
||||
</rdf:Description>
|
||||
<rdf:Description
|
||||
rdf:about="uuid:609bc623-b01c-476b-9349-300763160df1">
|
||||
<dc:format>
|
||||
image/svg+xml</dc:format>
|
||||
<dc:title>
|
||||
<rdf:Alt>
|
||||
<rdf:li
|
||||
xml:lang="x-default">
|
||||
test.ai</rdf:li>
|
||||
</rdf:Alt>
|
||||
</dc:title>
|
||||
</rdf:Description>
|
||||
</rdf:RDF>
|
||||
</x:xmpmeta>
|
||||
<xpacket>end='w' </xpacket>
|
||||
</metadata>
|
||||
<rect
|
||||
id="_x3C_Slice_x3E_"
|
||||
style="font-size:12;fill:none;"
|
||||
width="256"
|
||||
height="256" />
|
||||
<path
|
||||
style="font-size:12;opacity:0.2;"
|
||||
d="M221.848,47.811c0,0-130.558,89.471-132.578,90.855c-1.689-1.683-41.779-41.595-41.779-41.595 c-2.978-2.968-6.891-4.068-10.467-2.943c-3.89,1.232-6.403,4.005-7.08,7.809l-0.42,2.363c-0.135,0.765-0.122,1.532,0.037,2.285 l0.589,2.802l0.408,1.247l46.254,101.694c1.449,3.183,4.375,5.427,7.83,6.001c3.441,0.579,6.936-0.598,9.349-3.144 L235.225,65.893c2.066-2.169,3.252-5.263,3.252-8.481l-0.129-1.236l-0.572-2.723c-0.697-3.33-2.852-5.804-6.227-7.157 C229.395,45.431,225.963,44.991,221.848,47.811z"
|
||||
id="path552" />
|
||||
<path
|
||||
style="font-size:12;opacity:0.2;"
|
||||
d="M218.848,47.811c0,0-130.558,89.471-132.578,90.855c-1.689-1.683-41.779-41.595-41.779-41.595 c-2.978-2.968-6.891-4.068-10.467-2.943c-3.89,1.232-6.403,4.005-7.08,7.809l-0.42,2.363c-0.135,0.765-0.122,1.532,0.037,2.285 l0.589,2.802l0.408,1.247l46.254,101.694c1.449,3.183,4.375,5.427,7.83,6.001c3.441,0.579,6.936-0.598,9.349-3.144 L232.225,65.893c2.066-2.169,3.252-5.263,3.252-8.481l-0.129-1.236l-0.572-2.723c-0.697-3.33-2.852-5.804-6.227-7.157 C226.395,45.431,222.963,44.991,218.848,47.811z"
|
||||
id="path553" />
|
||||
<path
|
||||
style="font-size:12;opacity:0.2;"
|
||||
d="M217.848,45.811c0,0-130.558,89.471-132.578,90.855c-1.689-1.683-41.779-41.595-41.779-41.595 c-2.978-2.968-6.891-4.068-10.467-2.943c-3.89,1.232-6.403,4.005-7.08,7.809l-0.42,2.363c-0.135,0.765-0.122,1.532,0.037,2.285 l0.589,2.802l0.408,1.247l46.254,101.694c1.449,3.183,4.375,5.427,7.83,6.001c3.441,0.579,6.936-0.598,9.349-3.144 L231.225,63.893c2.066-2.169,3.252-5.263,3.252-8.481l-0.129-1.236l-0.572-2.723c-0.697-3.33-2.852-5.804-6.227-7.157 C225.395,43.431,221.963,42.991,217.848,45.811z"
|
||||
id="path554" />
|
||||
<path
|
||||
style="font-size:12;fill:url(#XMLID_5_);"
|
||||
d="M215.848,43.811c0,0-130.558,89.471-132.578,90.855 c-1.689-1.683-41.779-41.595-41.779-41.595c-2.978-2.968-6.891-4.068-10.467-2.943c-3.89,1.232-6.403,4.005-7.08,7.809 l-0.42,2.363c-0.135,0.765-0.122,1.532,0.037,2.285l0.589,2.802l0.408,1.247l46.254,101.694c1.449,3.183,4.375,5.427,7.83,6.001 c3.441,0.579,6.936-0.598,9.349-3.144L229.225,61.893c2.066-2.169,3.252-5.263,3.252-8.481l-0.129-1.236l-0.572-2.723 c-0.697-3.33-2.852-5.804-6.227-7.157C223.395,41.431,219.963,40.991,215.848,43.811z"
|
||||
id="path561" />
|
||||
<path
|
||||
style="font-size:12;fill:url(#XMLID_6_);"
|
||||
d="M219.239,48.761c0,0-135.454,92.824-136.679,93.665 c-5.106-5.083-45.302-45.103-45.302-45.103c-1.187-1.182-2.833-1.976-4.431-1.472c-1.597,0.505-2.684,1.485-2.977,3.135 l-0.42,2.364l0.589,2.802c0.007,0.016,46.252,101.691,46.252,101.691c0.621,1.363,1.876,2.321,3.354,2.567 c1.477,0.247,2.978-0.265,4.008-1.353L224.865,57.77c1.021-1.072,1.611-2.665,1.611-4.358l-0.572-2.728 c-0.309-1.471-1.192-2.26-2.588-2.82C221.922,47.305,220.477,47.913,219.239,48.761z"
|
||||
id="path568" />
|
||||
<path
|
||||
style="font-size:12;fill:url(#XMLID_7_);"
|
||||
d="M84.485,146.561c-1.425,0.977-3.344,0.803-4.567-0.416c0,0-44.921-44.724-45.833-45.632 c-0.091,0.252-0.154,0.533-0.154,0.838c0,0.328,0.06,0.662,0.192,0.955c0,0,46.096,101.347,46.241,101.664 c0.877-0.93,141.232-149.292,141.232-149.292c0.232-0.243,0.381-0.741,0.381-1.266c0-0.322-0.074-0.645-0.2-0.935 C220.751,53.177,84.485,146.561,84.485,146.561z"
|
||||
id="path575" />
|
||||
<path
|
||||
style="font-size:12;fill:url(#XMLID_8_);"
|
||||
d="M86.517,149.525c-0.001,0-0.001,0.004-0.001,0.004 c-2.848,1.947-6.69,1.596-9.133-0.838c0,0-20.052-19.966-33.287-33.141c10.589,23.282,30.678,67.45,37.327,82.069 c6.078-6.424,93.826-99.178,119.981-126.826C170.026,92.297,86.517,149.525,86.517,149.525z"
|
||||
id="path582" />
|
||||
</svg>
|
Before Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 278 B |
Before Width: | Height: | Size: 335 B |
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 7.9 KiB |
Before Width: | Height: | Size: 765 B |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 4.1 KiB |
Before Width: | Height: | Size: 786 B |
Before Width: | Height: | Size: 675 B |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 2.3 KiB |
|
@ -1,819 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
|
||||
|
||||
<svg
|
||||
xmlns:pdf="http://ns.adobe.com/pdf/1.3/"
|
||||
xmlns:xapMM="http://ns.adobe.com/xap/1.0/mm/"
|
||||
xmlns:xapGImg="http://ns.adobe.com/xap/1.0/g/img/"
|
||||
xmlns:xap="http://ns.adobe.com/xap/1.0/"
|
||||
xmlns:ns0="http://ns.adobe.com/SaveForWeb/1.0/"
|
||||
xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
|
||||
xmlns:x="adobe:ns:meta/"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="48pt"
|
||||
height="48pt"
|
||||
viewBox="0 0 256 256"
|
||||
overflow="visible"
|
||||
enable-background="new 0 0 256 256"
|
||||
xml:space="preserve"
|
||||
id="svg710"
|
||||
sodipodi:version="0.32"
|
||||
sodipodi:docname="application-text.svg"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.1 r9760">
|
||||
<defs
|
||||
id="defs796">
|
||||
|
||||
|
||||
|
||||
<linearGradient
|
||||
y2="245.0005"
|
||||
x2="128.9995"
|
||||
y1="11"
|
||||
x1="128.9995"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="XMLID_9_">
|
||||
<stop
|
||||
id="stop717"
|
||||
style="stop-color:#494949"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop718"
|
||||
style="stop-color:#000000"
|
||||
offset="1" />
|
||||
<a:midPointStop
|
||||
id="midPointStop719"
|
||||
style="stop-color:#494949"
|
||||
offset="0" />
|
||||
<a:midPointStop
|
||||
id="midPointStop720"
|
||||
style="stop-color:#494949"
|
||||
offset="0.5" />
|
||||
<a:midPointStop
|
||||
id="midPointStop721"
|
||||
style="stop-color:#000000"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
|
||||
|
||||
<linearGradient
|
||||
y2="226.9471"
|
||||
x2="226.9471"
|
||||
y1="29.0532"
|
||||
x1="29.0532"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="XMLID_10_">
|
||||
<stop
|
||||
id="stop725"
|
||||
style="stop-color:#FFFFFF"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop726"
|
||||
style="stop-color:#DADADA"
|
||||
offset="1" />
|
||||
<a:midPointStop
|
||||
id="midPointStop727"
|
||||
style="stop-color:#FFFFFF"
|
||||
offset="0" />
|
||||
<a:midPointStop
|
||||
id="midPointStop728"
|
||||
style="stop-color:#FFFFFF"
|
||||
offset="0.5" />
|
||||
<a:midPointStop
|
||||
id="midPointStop729"
|
||||
style="stop-color:#DADADA"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<linearGradient
|
||||
gradientTransform="matrix(0.1991,0.98,-0.98,0.1991,91.6944,573.5653)"
|
||||
y2="-164.2214"
|
||||
x2="-360.2456"
|
||||
y1="-94.4194"
|
||||
x1="-481.7007"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="XMLID_11_">
|
||||
<stop
|
||||
id="stop736"
|
||||
style="stop-color:#990000"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop737"
|
||||
style="stop-color:#7C0000"
|
||||
offset="1" />
|
||||
<a:midPointStop
|
||||
id="midPointStop738"
|
||||
style="stop-color:#990000"
|
||||
offset="0" />
|
||||
<a:midPointStop
|
||||
id="midPointStop739"
|
||||
style="stop-color:#990000"
|
||||
offset="0.5" />
|
||||
<a:midPointStop
|
||||
id="midPointStop740"
|
||||
style="stop-color:#7C0000"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
|
||||
<linearGradient
|
||||
gradientTransform="matrix(-0.999,0.0435,0.0435,0.999,-1277.0056,-496.5172)"
|
||||
y2="706.3217"
|
||||
x2="-1355.0455"
|
||||
y1="685.3809"
|
||||
x1="-1375.9844"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="XMLID_12_">
|
||||
<stop
|
||||
id="stop743"
|
||||
style="stop-color:#F8F1DC"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop744"
|
||||
style="stop-color:#D6A84A"
|
||||
offset="1" />
|
||||
<a:midPointStop
|
||||
id="midPointStop745"
|
||||
style="stop-color:#F8F1DC"
|
||||
offset="0" />
|
||||
<a:midPointStop
|
||||
id="midPointStop746"
|
||||
style="stop-color:#F8F1DC"
|
||||
offset="0.5" />
|
||||
<a:midPointStop
|
||||
id="midPointStop747"
|
||||
style="stop-color:#D6A84A"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
|
||||
<linearGradient
|
||||
y2="160.1823"
|
||||
x2="137.6021"
|
||||
y1="-0.7954"
|
||||
x1="65.0947"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="XMLID_13_">
|
||||
<stop
|
||||
id="stop750"
|
||||
style="stop-color:#FFA700"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop751"
|
||||
style="stop-color:#FFD700"
|
||||
offset="0.7753" />
|
||||
<stop
|
||||
id="stop752"
|
||||
style="stop-color:#FF794B"
|
||||
offset="1" />
|
||||
<a:midPointStop
|
||||
id="midPointStop753"
|
||||
style="stop-color:#FFA700"
|
||||
offset="0" />
|
||||
<a:midPointStop
|
||||
id="midPointStop754"
|
||||
style="stop-color:#FFA700"
|
||||
offset="0.5" />
|
||||
<a:midPointStop
|
||||
id="midPointStop755"
|
||||
style="stop-color:#FFD700"
|
||||
offset="0.7753" />
|
||||
<a:midPointStop
|
||||
id="midPointStop756"
|
||||
style="stop-color:#FFD700"
|
||||
offset="0.5" />
|
||||
<a:midPointStop
|
||||
id="midPointStop757"
|
||||
style="stop-color:#FF794B"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
|
||||
|
||||
|
||||
|
||||
<linearGradient
|
||||
gradientTransform="matrix(-0.999,0.0435,0.0435,0.999,-1277.0056,-496.5172)"
|
||||
y2="622.5333"
|
||||
x2="-1325.3219"
|
||||
y1="635.7949"
|
||||
x1="-1336.4497"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="XMLID_14_">
|
||||
<stop
|
||||
id="stop763"
|
||||
style="stop-color:#FFC957"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop764"
|
||||
style="stop-color:#FF6D00"
|
||||
offset="1" />
|
||||
<a:midPointStop
|
||||
id="midPointStop765"
|
||||
style="stop-color:#FFC957"
|
||||
offset="0" />
|
||||
<a:midPointStop
|
||||
id="midPointStop766"
|
||||
style="stop-color:#FFC957"
|
||||
offset="0.5" />
|
||||
<a:midPointStop
|
||||
id="midPointStop767"
|
||||
style="stop-color:#FF6D00"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
|
||||
<linearGradient
|
||||
gradientTransform="matrix(-0.999,0.0435,0.0435,0.999,-1277.0056,-496.5172)"
|
||||
y2="699.4763"
|
||||
x2="-1354.6851"
|
||||
y1="595.6309"
|
||||
x1="-1401.459"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="XMLID_15_">
|
||||
<stop
|
||||
id="stop770"
|
||||
style="stop-color:#FFA700"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop771"
|
||||
style="stop-color:#FFD700"
|
||||
offset="0.7753" />
|
||||
<stop
|
||||
id="stop772"
|
||||
style="stop-color:#FF9200"
|
||||
offset="1" />
|
||||
<a:midPointStop
|
||||
id="midPointStop773"
|
||||
style="stop-color:#FFA700"
|
||||
offset="0" />
|
||||
<a:midPointStop
|
||||
id="midPointStop774"
|
||||
style="stop-color:#FFA700"
|
||||
offset="0.5" />
|
||||
<a:midPointStop
|
||||
id="midPointStop775"
|
||||
style="stop-color:#FFD700"
|
||||
offset="0.7753" />
|
||||
<a:midPointStop
|
||||
id="midPointStop776"
|
||||
style="stop-color:#FFD700"
|
||||
offset="0.5" />
|
||||
<a:midPointStop
|
||||
id="midPointStop777"
|
||||
style="stop-color:#FF9200"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
|
||||
<linearGradient
|
||||
y2="115.5361"
|
||||
x2="144.5898"
|
||||
y1="115.5361"
|
||||
x1="67.8452"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="XMLID_16_">
|
||||
<stop
|
||||
id="stop780"
|
||||
style="stop-color:#7D7D99"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop781"
|
||||
style="stop-color:#B1B1C5"
|
||||
offset="0.1798" />
|
||||
<stop
|
||||
id="stop782"
|
||||
style="stop-color:#BCBCC8"
|
||||
offset="0.3727" />
|
||||
<stop
|
||||
id="stop783"
|
||||
style="stop-color:#C8C8CB"
|
||||
offset="0.6825" />
|
||||
<stop
|
||||
id="stop784"
|
||||
style="stop-color:#CCCCCC"
|
||||
offset="1" />
|
||||
<a:midPointStop
|
||||
id="midPointStop785"
|
||||
style="stop-color:#7D7D99"
|
||||
offset="0" />
|
||||
<a:midPointStop
|
||||
id="midPointStop786"
|
||||
style="stop-color:#7D7D99"
|
||||
offset="0.5" />
|
||||
<a:midPointStop
|
||||
id="midPointStop787"
|
||||
style="stop-color:#B1B1C5"
|
||||
offset="0.1798" />
|
||||
<a:midPointStop
|
||||
id="midPointStop788"
|
||||
style="stop-color:#B1B1C5"
|
||||
offset="0.2881" />
|
||||
<a:midPointStop
|
||||
id="midPointStop789"
|
||||
style="stop-color:#CCCCCC"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#XMLID_16_"
|
||||
id="linearGradient80060"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="67.8452"
|
||||
y1="115.5361"
|
||||
x2="144.5898"
|
||||
y2="115.5361"
|
||||
gradientTransform="translate(0,-25.600002)" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#XMLID_15_"
|
||||
id="linearGradient80063"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(-0.999,0.0435,0.0435,0.999,-1277.0056,-522.11722)"
|
||||
x1="-1401.459"
|
||||
y1="595.6309"
|
||||
x2="-1354.6851"
|
||||
y2="699.4763" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#XMLID_14_"
|
||||
id="linearGradient80066"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(-0.999,0.0435,0.0435,0.999,-1277.0056,-522.11722)"
|
||||
x1="-1336.4497"
|
||||
y1="635.7949"
|
||||
x2="-1325.3219"
|
||||
y2="622.5333" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#XMLID_13_"
|
||||
id="linearGradient80072"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="65.0947"
|
||||
y1="-0.7954"
|
||||
x2="137.6021"
|
||||
y2="160.1823"
|
||||
gradientTransform="translate(0,-25.600002)" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#XMLID_12_"
|
||||
id="linearGradient80075"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(-0.999,0.0435,0.0435,0.999,-1277.0056,-522.11722)"
|
||||
x1="-1375.9844"
|
||||
y1="685.3809"
|
||||
x2="-1355.0455"
|
||||
y2="706.3217" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#XMLID_11_"
|
||||
id="linearGradient80078"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.1991,0.98,-0.98,0.1991,91.6944,547.96528)"
|
||||
x1="-481.7007"
|
||||
y1="-94.4194"
|
||||
x2="-360.2456"
|
||||
y2="-164.2214" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#XMLID_10_"
|
||||
id="linearGradient80085"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="29.0532"
|
||||
y1="29.0532"
|
||||
x2="226.9471"
|
||||
y2="226.9471" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#XMLID_9_"
|
||||
id="linearGradient80089"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="128.9995"
|
||||
y1="11"
|
||||
x2="128.9995"
|
||||
y2="245.0005" /></defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
showgrid="false"
|
||||
inkscape:zoom="3.6203867"
|
||||
inkscape:cx="24.932695"
|
||||
inkscape:cy="18.484388"
|
||||
inkscape:window-width="1280"
|
||||
inkscape:window-height="766"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="20"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="svg710" />
|
||||
<metadata
|
||||
id="metadata711">
|
||||
<ns0:sfw>
|
||||
<ns0:slices>
|
||||
<ns0:slice
|
||||
x="0"
|
||||
y="0"
|
||||
width="256"
|
||||
height="256"
|
||||
sliceID="124333141" />
|
||||
</ns0:slices>
|
||||
<ns0:sliceSourceBounds
|
||||
x="0"
|
||||
y="0"
|
||||
width="256"
|
||||
height="256"
|
||||
bottomLeftOrigin="true" />
|
||||
<ns0:optimizationSettings>
|
||||
<ns0:targetSettings
|
||||
fileFormat="PNG24Format"
|
||||
targetSettingsID="0">
|
||||
<ns0:PNG24Format
|
||||
transparency="true"
|
||||
includeCaption="false"
|
||||
interlaced="false"
|
||||
noMatteColor="false"
|
||||
matteColor="#FFFFFF"
|
||||
filtered="false" />
|
||||
</ns0:targetSettings>
|
||||
</ns0:optimizationSettings>
|
||||
</ns0:sfw>
|
||||
<xpacket
|
||||
id="xpacket79197">begin='' id='W5M0MpCehiHzreSzNTczkc9d' </xpacket>
|
||||
<x:xmpmeta
|
||||
x:xmptk="XMP toolkit 3.0-29, framework 1.6">
|
||||
|
||||
<metadata
|
||||
id="metadata79254"><rdf:RDF>
|
||||
<rdf:Description
|
||||
rdf:about="uuid:cbee75c6-82d1-45ba-8274-b89c6084675c">
|
||||
<pdf:Producer>
|
||||
Adobe PDF library 5.00</pdf:Producer>
|
||||
</rdf:Description>
|
||||
<rdf:Description
|
||||
rdf:about="uuid:cbee75c6-82d1-45ba-8274-b89c6084675c" />
|
||||
<rdf:Description
|
||||
rdf:about="uuid:cbee75c6-82d1-45ba-8274-b89c6084675c" />
|
||||
<rdf:Description
|
||||
rdf:about="uuid:cbee75c6-82d1-45ba-8274-b89c6084675c">
|
||||
<xap:CreateDate>
|
||||
2004-01-26T11:58:28+02:00</xap:CreateDate>
|
||||
<xap:ModifyDate>
|
||||
2004-03-28T20:41:40Z</xap:ModifyDate>
|
||||
<xap:CreatorTool>
|
||||
Adobe Illustrator 10.0</xap:CreatorTool>
|
||||
<xap:MetadataDate>
|
||||
2004-02-16T23:58:32+01:00</xap:MetadataDate>
|
||||
<xap:Thumbnails>
|
||||
<rdf:Alt>
|
||||
<rdf:li
|
||||
rdf:parseType="Resource">
|
||||
<xapGImg:format>
|
||||
JPEG</xapGImg:format>
|
||||
<xapGImg:width>
|
||||
256</xapGImg:width>
|
||||
<xapGImg:height>
|
||||
256</xapGImg:height>
|
||||
<xapGImg:image>
|
||||
/9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA
|
||||
AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK
|
||||
DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f
|
||||
Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgBAAEAAwER
|
||||
AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA
|
||||
AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB
|
||||
UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE
|
||||
1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ
|
||||
qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy
|
||||
obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp
|
||||
0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo
|
||||
+DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q7FXYq7FXYq7FXYq7
|
||||
FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYqlvmDzFo
|
||||
3l7TJdT1e5W1tItuTbszHoiKN2Y+AxV4j5g/5ydvTcMnl/SYlgU0Se/LOzDxMcTIF/4M4qk//QzP
|
||||
nv8A5YNL/wCRVx/2UYq7/oZnz3/ywaX/AMirj/soxV3/AEMz57/5YNL/AORVx/2UYq7/AKGZ89/8
|
||||
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
|
||||
f//Z</xapGImg:image>
|
||||
</rdf:li>
|
||||
</rdf:Alt>
|
||||
</xap:Thumbnails>
|
||||
</rdf:Description>
|
||||
<rdf:Description
|
||||
rdf:about="uuid:cbee75c6-82d1-45ba-8274-b89c6084675c">
|
||||
<xapMM:DocumentID>
|
||||
uuid:4ee3f24b-6ed2-4a2e-8f7a-50b762c8da8b</xapMM:DocumentID>
|
||||
</rdf:Description>
|
||||
<rdf:Description
|
||||
rdf:about="uuid:cbee75c6-82d1-45ba-8274-b89c6084675c">
|
||||
<dc:format>
|
||||
image/svg+xml</dc:format>
|
||||
<dc:title>
|
||||
<rdf:Alt>
|
||||
<rdf:li
|
||||
xml:lang="x-default">
|
||||
mime.ai</rdf:li>
|
||||
</rdf:Alt>
|
||||
</dc:title>
|
||||
</rdf:Description>
|
||||
<cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata></x:xmpmeta>
|
||||
<xpacket
|
||||
id="xpacket79199">end='w' </xpacket>
|
||||
</metadata>
|
||||
<path
|
||||
style="opacity:0.2"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path713"
|
||||
d="m 44,15.5 c -9.374,0 -17,7.626 -17,17 v 200 c 0,9.374 7.626,17 17,17 h 176 c 9.375,0 17,-7.626 17,-17 v -200 c 0,-9.374 -7.625,-17 -17,-17 H 44 z" /><path
|
||||
style="opacity:0.2"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path714"
|
||||
d="m 42,13.5 c -9.374,0 -17,7.626 -17,17 v 200 c 0,9.374 7.626,17 17,17 h 176 c 9.375,0 17,-7.626 17,-17 v -200 c 0,-9.374 -7.625,-17 -17,-17 H 42 z" /><path
|
||||
style="opacity:0.2"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path715"
|
||||
d="m 40,12.5 c -9.374,0 -17,7.626 -17,17 v 200 c 0,9.374 7.626,17 17,17 h 176 c 9.375,0 17,-7.626 17,-17 v -200 c 0,-9.374 -7.625,-17 -17,-17 H 40 z" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:url(#linearGradient80089)"
|
||||
id="path722"
|
||||
d="m 41,11 c -9.374,0 -17,7.626 -17,17 v 200 c 0,9.374 7.626,17 17,17 h 176 c 9.375,0 17,-7.626 17,-17 V 28 c 0,-9.374 -7.625,-17 -17,-17 H 41 z" /><path
|
||||
style="fill:#ffffff"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path723"
|
||||
d="m 28,228 c 0,6.627 5.373,12 12,12 h 176 c 6.627,0 12,-5.373 12,-12 V 28 c 0,-6.627 -5.373,-12 -12,-12 H 40 c -6.627,0 -12,5.373 -12,12 v 200 z" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:url(#linearGradient80085)"
|
||||
id="path730"
|
||||
d="m 40,21 c -3.86,0 -7,3.14 -7,7 v 200 c 0,3.859 3.14,7 7,7 h 176 c 3.859,0 7,-3.141 7,-7 V 28 c 0,-3.86 -3.141,-7 -7,-7 H 40 z" /><path
|
||||
style="opacity:0.2"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path731"
|
||||
d="m 191.924,170.38398 c -11.613,-36.12699 -13.717,-42.66999 -14.859,-44.06399 0.119,0.076 0.289,0.178 0.289,0.178 L 98.804,39.042999 c -4.195,-4.65 -14.005,0.356 -21.355,6.976 -7.283,6.542 -13.32,15.772999 -9.37,20.563999 l 78.944,87.542982 0.533,0.094 37.768,17.602 7.688,2.365 -1.088,-3.803 z" /><path
|
||||
style="opacity:0.2"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path732"
|
||||
d="m 193.557,167.91598 c -11.611,-36.12499 -13.713,-42.66999 -14.855,-44.06399 0.117,0.072 0.287,0.178 0.287,0.178 L 100.444,36.574999 c -4.199,-4.651 -14.015,0.355 -21.361,6.975 -7.281,6.545 -13.32,15.772999 -9.368,20.565999 l 78.945,87.538982 0.533,0.1 37.77,17.598 7.682,2.367 -1.088,-3.804 z" /><path
|
||||
style="opacity:0.2"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path733"
|
||||
d="M 186.773,165.44898 C 175.16,129.32199 173.06,122.77699 171.91,121.38099 c 0.121,0.074 0.295,0.18 0.295,0.18 L 93.653,34.103999 c -4.192,-4.65 -14.009,0.359 -21.354,6.978 -7.283,6.542 -13.321,15.770999 -9.369,20.564999 l 78.942,87.540982 0.535,0.096 37.768,17.598 7.686,2.367 -1.088,-3.8 z" /><path
|
||||
style="fill:#ffffff"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path734"
|
||||
d="m 186.43,163.75498 c -11.613,-36.12499 -13.713,-42.66599 -14.863,-44.06099 0.123,0.072 0.293,0.18 0.293,0.18 L 93.314,32.415999 c -4.199,-4.651 -14.015,0.357 -21.359,6.977 -7.283,6.543 -13.322,15.773999 -9.37,20.565999 l 78.941,87.540982 0.535,0.098 37.771,17.598 7.686,2.363 -1.088,-3.804 z" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:url(#linearGradient80078)"
|
||||
id="path741"
|
||||
d="m 186.43,163.75498 c -11.613,-36.12499 -13.713,-42.66599 -14.863,-44.06099 0.123,0.072 0.293,0.18 0.293,0.18 L 93.314,32.415999 c -4.199,-4.651 -14.015,0.357 -21.359,6.977 -7.283,6.543 -13.322,15.773999 -9.37,20.565999 l 78.941,87.540982 0.535,0.098 37.771,17.598 7.686,2.363 -1.088,-3.804 z" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:url(#linearGradient80075)"
|
||||
id="path748"
|
||||
d="m 166.969,122.16199 13.723,38.12899 -36.371,-17.90199 0.168,-0.152 c -0.25,-0.08 -0.496,-0.178 -0.701,-0.316 l -0.125,0.121 -75.303,-83.569992 0.123,-0.104 c -2.246,-2.49 1.032,-9.093999 7.308,-14.751999 6.28,-5.652 13.18,-8.219 15.425,-5.733 l 75.292,83.564991 0.461,0.714 z" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:url(#linearGradient80072)"
|
||||
id="path758"
|
||||
d="m 148.652,144.52098 c 2.076,-0.369 4.635,-1.479 7.252,-3.13899 1.617,-1.018 3.279,-2.283 4.898,-3.744 1.455,-1.303 2.736,-2.666 3.84,-4.01 2.076,-2.531 3.322,-5.213 3.781,-7.424 l -1.455,-4.043 -0.463,-0.715 -74.798,-83.017991 c 0.608,2.24 -0.962,5.938 -4.063,9.74 -1.134,1.389 -2.441,2.789 -3.945,4.141 -1.574,1.418999 -3.195,2.651999 -4.767,3.653999 -4.493,2.871 -8.628,3.928 -10.548,2.486 l -0.025,0.021 75.303,83.569992 0.125,-0.121 c 0.205,0.139 0.451,0.236 0.701,0.316 l -0.168,0.152 4.332,2.13399 z" /><path
|
||||
style="fill:#ffffff"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path759"
|
||||
d="m 68.083,57.809998 c 1.732,1.772 5.994,0.776 10.643,-2.194 1.541,-0.982 3.132,-2.193 4.677,-3.585999 1.476,-1.325 2.759,-2.701 3.872,-4.063 3.578,-4.388 5.091,-8.642 3.477,-10.584 l 0.023,-0.024 75.817,84.118991 c 0.635,2.262 -0.588,6.498 -3.754,10.357 -1.082,1.318 -2.34,2.656 -3.77,3.934 -1.588,1.434 -3.219,2.676 -4.807,3.676 -4.74,3.006 -9.303,4.19899 -11.016,2.301 -0.393,-0.439 -2.098,-2.336 -2.145,-2.406 l -73.255,-81.313992 0.238,-0.216 z" /><path
|
||||
style="fill:#ffffff"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path760"
|
||||
d="m 75.79,43.614999 c 6.28,-5.652 13.18,-8.219 15.425,-5.733 l 16.961,18.827999 1.152,26.49 -17.973,0.784 -22.996,-25.513 0.123,-0.104 c -2.246,-2.49 1.032,-9.092999 7.308,-14.751999 z" /><path
|
||||
style="fill:#ffffff"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path761"
|
||||
d="m 68.083,57.809998 c 1.732,1.772 5.994,0.776 10.643,-2.194 1.541,-0.982 3.132,-2.193 4.677,-3.585999 1.476,-1.325 2.759,-2.701 3.872,-4.063 3.578,-4.388 5.091,-8.642 3.477,-10.584 l 0.023,-0.024 75.817,84.118991 c 0.635,2.262 -0.588,6.498 -3.754,10.357 -1.082,1.318 -2.34,2.656 -3.77,3.934 -1.588,1.434 -3.219,2.676 -4.807,3.676 -4.74,3.006 -9.303,4.19899 -11.016,2.301 -0.393,-0.439 -2.098,-2.336 -2.145,-2.406 l -73.255,-81.313992 0.238,-0.216 z" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:url(#linearGradient80066)"
|
||||
id="path768"
|
||||
d="m 75.79,43.614999 c 6.28,-5.652 13.18,-8.219 15.425,-5.733 l 16.961,18.827999 1.152,26.49 -17.973,0.784 -22.996,-25.513 0.123,-0.104 c -2.246,-2.49 1.032,-9.092999 7.308,-14.751999 z" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:url(#linearGradient80063)"
|
||||
id="path778"
|
||||
d="m 68.083,57.809998 c 1.732,1.772 5.994,0.776 10.643,-2.194 1.541,-0.982 3.132,-2.193 4.677,-3.585999 1.476,-1.325 2.759,-2.701 3.872,-4.063 3.578,-4.388 5.091,-8.642 3.477,-10.584 l 0.023,-0.024 75.817,84.118991 c 0.635,2.262 -0.588,6.498 -3.754,10.357 -1.082,1.318 -2.34,2.656 -3.77,3.934 -1.588,1.434 -3.219,2.676 -4.807,3.676 -4.74,3.006 -9.303,4.19899 -11.016,2.301 -0.393,-0.439 -2.098,-2.336 -2.145,-2.406 l -73.255,-81.313992 0.238,-0.216 z" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:url(#linearGradient80060)"
|
||||
id="path790"
|
||||
d="m 74.357,65.112998 c 0,0 6.036,-0.212 10.685,-3.182 1.542,-0.983 3.132,-2.193 4.677,-3.586 1.477,-1.326 2.76,-2.701 3.873,-4.064 2.928,-3.588999 4.469,-7.087999 4.049,-9.306999 l -6.865,-7.617 -0.023,0.024 c 1.614,1.942 0.102,6.196 -3.477,10.584 -1.113,1.362 -2.396,2.738 -3.872,4.063 -1.545,1.392999 -3.136,2.603999 -4.677,3.585999 -4.648,2.971 -8.91,3.967 -10.643,2.194 l -0.238,0.217 73.256,81.310992 c 0.047,0.07 1.752,1.967 2.145,2.406 0.342,0.377 0.799,0.627 1.344,0.771 L 74.357,65.112998 z" /><path
|
||||
style="fill:#003333"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path791"
|
||||
d="m 172.035,149.75398 c -1.635,1.477 -3.307,2.764 -4.949,3.84 l 13.605,6.697 -5.096,-14.156 c -1.058,1.218 -2.243,2.441 -3.56,3.619 z" /><path
|
||||
style="opacity:0.5;fill:#ffffff"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path792"
|
||||
d="M 163.121,131.45299 86.968,48.329999 c 0.1,-0.12 0.213,-0.242 0.307,-0.364 1.428,-1.752 2.52,-3.49 3.225,-5.058 l 75.768,82.706991 c -0.553,1.824 -1.6,3.867 -3.147,5.838 z" /><path
|
||||
style="opacity:0.5;fill:#ffffff"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path793"
|
||||
d="m 87.275,47.965999 c 0.634,-0.774 1.189,-1.548 1.694,-2.3 l 76.015,82.973991 c -0.578,1.063 -1.283,2.146 -2.146,3.193 -0.744,0.896 -1.566,1.805 -2.465,2.697 L 84.152,51.331999 c 1.164,-1.108 2.209,-2.24 3.123,-3.366 z" /><rect
|
||||
style="fill:none"
|
||||
y="0"
|
||||
x="0"
|
||||
height="256"
|
||||
width="256"
|
||||
id="_x3C_Slice_x3E_" />
|
||||
<rect
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:4.26666689;stroke-opacity:1"
|
||||
id="rect79256"
|
||||
width="150.77966"
|
||||
height="48.813557"
|
||||
x="9.313406"
|
||||
y="170.86343"
|
||||
ry="0" /><text
|
||||
xml:space="preserve"
|
||||
style="font-size:42.66666794px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:justify;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Linux Libertine O C;-inkscape-font-specification:Linux Libertine O C"
|
||||
x="24.554667"
|
||||
y="207.10201"
|
||||
id="text80094"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan80096"
|
||||
x="24.554667"
|
||||
y="207.10201"
|
||||
style="font-style:italic;font-weight:bold;-inkscape-font-specification:Linux Libertine O C Bold Italic">Labels</tspan></text>
|
||||
</svg>
|
Before Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 977 B |
Before Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 2.0 KiB |
|
@ -1,577 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
<svg
|
||||
xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
|
||||
xmlns:i="http://ns.adobe.com/AdobeIllustrator/10.0/"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://web.resource.org/cc/"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.0"
|
||||
width="48pt"
|
||||
height="48pt"
|
||||
viewBox="0 0 256 256"
|
||||
id="svg2"
|
||||
xml:space="preserve"
|
||||
sodipodi:version="0.32"
|
||||
inkscape:version="0.42+devel"
|
||||
sodipodi:docname="gtk-open2.svg"
|
||||
sodipodi:docbase="/home/cschalle/gnome/gnome-themes-extras/Nuvola/icons/scalable/stock"><metadata
|
||||
id="metadata85"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><sodipodi:namedview
|
||||
inkscape:cy="417.84947"
|
||||
inkscape:cx="305.25953"
|
||||
inkscape:zoom="0.43415836"
|
||||
inkscape:window-height="563"
|
||||
inkscape:window-width="822"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
borderopacity="1.0"
|
||||
bordercolor="#666666"
|
||||
pagecolor="#ffffff"
|
||||
id="base"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="30"
|
||||
inkscape:current-layer="svg2" /><defs
|
||||
id="defs151" />
|
||||
|
||||
<g
|
||||
id="switch6">
|
||||
<foreignObject
|
||||
id="foreignObject8"
|
||||
height="1"
|
||||
width="1"
|
||||
y="0"
|
||||
x="0"
|
||||
requiredExtensions="http://ns.adobe.com/AdobeIllustrator/10.0/">
|
||||
<i:pgfRef
|
||||
xlink:href="#adobe_illustrator_pgf">
|
||||
</i:pgfRef>
|
||||
</foreignObject>
|
||||
<g
|
||||
id="g10">
|
||||
<g
|
||||
id="Layer_1">
|
||||
<rect
|
||||
width="256"
|
||||
height="256"
|
||||
x="0"
|
||||
y="0"
|
||||
style="fill:none"
|
||||
id="rect13" />
|
||||
</g>
|
||||
<g
|
||||
id="Layer_2">
|
||||
<linearGradient
|
||||
x1="98.551804"
|
||||
y1="41.2593"
|
||||
x2="98.551804"
|
||||
y2="214.72549"
|
||||
id="XMLID_14_"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop
|
||||
style="stop-color:#c9e6ff;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop17" />
|
||||
<stop
|
||||
style="stop-color:#006dff;stop-opacity:1"
|
||||
offset="0.55620003"
|
||||
id="stop19" />
|
||||
<stop
|
||||
style="stop-color:#0035ed;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop21" />
|
||||
<a:midPointStop
|
||||
style="stop-color:#C9E6FF"
|
||||
offset="0" />
|
||||
<a:midPointStop
|
||||
style="stop-color:#C9E6FF"
|
||||
offset="0.5" />
|
||||
<a:midPointStop
|
||||
style="stop-color:#006DFF"
|
||||
offset="0.5562" />
|
||||
<a:midPointStop
|
||||
style="stop-color:#006DFF"
|
||||
offset="0.5" />
|
||||
<a:midPointStop
|
||||
style="stop-color:#0035ED"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
<path
|
||||
d="M 17.219,51.266 C 16.115,51.266 15.219,52.163 15.219,53.266 L 15.219,202.735 C 15.219,203.838 16.115,204.735 17.219,204.735 L 179.885,204.735 C 180.989,204.735 181.885,203.838 181.885,202.735 L 181.885,75.933 C 181.885,74.83 180.989,73.933 179.885,73.933 L 100.552,73.933 L 100.552,53.266 C 100.552,52.163 99.656,51.266 98.552,51.266 L 17.219,51.266 z "
|
||||
style="fill:url(#XMLID_14_)"
|
||||
id="path23" />
|
||||
<linearGradient
|
||||
x1="98.551804"
|
||||
y1="41.258801"
|
||||
x2="98.551804"
|
||||
y2="214.7274"
|
||||
id="XMLID_15_"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop
|
||||
style="stop-color:#dcf0ff;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop26" />
|
||||
<stop
|
||||
style="stop-color:#428aff;stop-opacity:1"
|
||||
offset="0.58990002"
|
||||
id="stop28" />
|
||||
<stop
|
||||
style="stop-color:#006dff;stop-opacity:1"
|
||||
offset="0.85949999"
|
||||
id="stop30" />
|
||||
<stop
|
||||
style="stop-color:#0035ed;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop32" />
|
||||
<a:midPointStop
|
||||
style="stop-color:#DCF0FF"
|
||||
offset="0" />
|
||||
<a:midPointStop
|
||||
style="stop-color:#DCF0FF"
|
||||
offset="0.5" />
|
||||
<a:midPointStop
|
||||
style="stop-color:#428AFF"
|
||||
offset="0.5899" />
|
||||
<a:midPointStop
|
||||
style="stop-color:#428AFF"
|
||||
offset="0.5" />
|
||||
<a:midPointStop
|
||||
style="stop-color:#006DFF"
|
||||
offset="0.8595" />
|
||||
<a:midPointStop
|
||||
style="stop-color:#006DFF"
|
||||
offset="0.5" />
|
||||
<a:midPointStop
|
||||
style="stop-color:#0035ED"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
<path
|
||||
d="M 20.219,56.266 C 20.219,61.91 20.219,194.091 20.219,199.735 C 25.891,199.735 171.213,199.735 176.885,199.735 C 176.885,194.154 176.885,84.514 176.885,78.933 C 171.33,78.933 95.552,78.933 95.552,78.933 C 95.552,78.933 95.552,60.651 95.552,56.266 C 90.2,56.266 25.572,56.266 20.219,56.266 z "
|
||||
style="fill:url(#XMLID_15_)"
|
||||
id="path34" />
|
||||
<linearGradient
|
||||
x1="98.551804"
|
||||
y1="41.2593"
|
||||
x2="98.551804"
|
||||
y2="214.72549"
|
||||
id="XMLID_16_"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop37" />
|
||||
<stop
|
||||
style="stop-color:#e9f2ff;stop-opacity:1"
|
||||
offset="0.1147"
|
||||
id="stop39" />
|
||||
<stop
|
||||
style="stop-color:#b0d2ff;stop-opacity:1"
|
||||
offset="0.35389999"
|
||||
id="stop41" />
|
||||
<stop
|
||||
style="stop-color:#579fff;stop-opacity:1"
|
||||
offset="0.6936"
|
||||
id="stop43" />
|
||||
<stop
|
||||
style="stop-color:#006dff;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop45" />
|
||||
<a:midPointStop
|
||||
style="stop-color:#FFFFFF"
|
||||
offset="0" />
|
||||
<a:midPointStop
|
||||
style="stop-color:#FFFFFF"
|
||||
offset="0.5424" />
|
||||
<a:midPointStop
|
||||
style="stop-color:#006DFF"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
<path
|
||||
d="M 179.885,73.933 L 100.552,73.933 L 100.552,53.266 C 100.552,52.163 99.656,51.266 98.552,51.266 L 17.219,51.266 C 16.115,51.266 15.219,52.163 15.219,53.266 L 15.219,57.266 L 91.552,57.266 C 92.656,57.266 93.552,58.163 93.552,59.266 L 93.552,79.933 L 172.885,79.933 C 173.989,79.933 174.885,80.83 174.885,81.933 L 174.885,204.735 L 179.885,204.735 C 180.989,204.735 181.885,203.838 181.885,202.735 L 181.885,75.933 C 181.885,74.83 180.988,73.933 179.885,73.933 z "
|
||||
style="fill:url(#XMLID_16_)"
|
||||
id="path47" />
|
||||
<linearGradient
|
||||
x1="106.9839"
|
||||
y1="98.599098"
|
||||
x2="106.9839"
|
||||
y2="206.73489"
|
||||
id="XMLID_17_"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop
|
||||
style="stop-color:#0099ff;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop50" />
|
||||
<stop
|
||||
style="stop-color:#0089e5;stop-opacity:1"
|
||||
offset="0.0937"
|
||||
id="stop52" />
|
||||
<stop
|
||||
style="stop-color:#00406b;stop-opacity:1"
|
||||
offset="0.54689997"
|
||||
id="stop54" />
|
||||
<stop
|
||||
style="stop-color:#00121e;stop-opacity:1"
|
||||
offset="0.85769999"
|
||||
id="stop56" />
|
||||
<stop
|
||||
style="stop-color:#000000;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop58" />
|
||||
<a:midPointStop
|
||||
style="stop-color:#0099FF"
|
||||
offset="0" />
|
||||
<a:midPointStop
|
||||
style="stop-color:#0099FF"
|
||||
offset="0.4689" />
|
||||
<a:midPointStop
|
||||
style="stop-color:#000000"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
<path
|
||||
d="M 32.083,106.599 L 32.083,206.734 L 42.083,206.734 C 42.083,180.445 42.083,111.718 42.083,108.599 C 45.222,108.599 143.57,108.599 181.884,108.599 L 181.884,98.599 L 40.083,98.599 C 35.665,98.599 32.083,102.181 32.083,106.599 z "
|
||||
style="opacity:0.3;fill:url(#XMLID_17_)"
|
||||
id="path60" />
|
||||
<linearGradient
|
||||
x1="6.3671999"
|
||||
y1="47.148399"
|
||||
x2="179.4046"
|
||||
y2="220.1859"
|
||||
id="XMLID_18_"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop
|
||||
style="stop-color:#0053bd;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop63" />
|
||||
<stop
|
||||
style="stop-color:#00008d;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop65" />
|
||||
<a:midPointStop
|
||||
style="stop-color:#0053BD"
|
||||
offset="0" />
|
||||
<a:midPointStop
|
||||
style="stop-color:#0053BD"
|
||||
offset="0.5" />
|
||||
<a:midPointStop
|
||||
style="stop-color:#00008D"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
<path
|
||||
d="M 179.885,63.933 L 110.552,63.933 L 110.552,53.266 C 110.552,46.639 105.18,41.266 98.552,41.266 L 17.219,41.266 C 10.591,41.266 5.219,46.639 5.219,53.266 L 5.219,75.933 L 5.219,202.735 C 5.219,209.362 10.591,214.735 17.219,214.735 L 98.552,214.735 L 179.885,214.735 C 186.512,214.735 191.885,209.362 191.885,202.735 L 191.885,75.933 C 191.885,69.305 186.512,63.933 179.885,63.933 z M 181.885,202.734 C 181.885,203.837 180.989,204.734 179.885,204.734 L 17.219,204.734 C 16.115,204.734 15.219,203.837 15.219,202.734 L 15.219,53.266 C 15.219,52.163 16.115,51.266 17.219,51.266 L 98.552,51.266 C 99.656,51.266 100.552,52.163 100.552,53.266 L 100.552,73.933 L 179.885,73.933 C 180.989,73.933 181.885,74.83 181.885,75.933 L 181.885,202.734 z "
|
||||
style="fill:url(#XMLID_18_)"
|
||||
id="path67" />
|
||||
<linearGradient
|
||||
x1="128.48441"
|
||||
y1="86.066902"
|
||||
x2="128.48441"
|
||||
y2="228.0708"
|
||||
id="XMLID_19_"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop
|
||||
style="stop-color:#c9e6ff;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop70" />
|
||||
<stop
|
||||
style="stop-color:#006dff;stop-opacity:1"
|
||||
offset="0.55620003"
|
||||
id="stop72" />
|
||||
<stop
|
||||
style="stop-color:#0035ed;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop74" />
|
||||
<a:midPointStop
|
||||
style="stop-color:#C9E6FF"
|
||||
offset="0" />
|
||||
<a:midPointStop
|
||||
style="stop-color:#C9E6FF"
|
||||
offset="0.5" />
|
||||
<a:midPointStop
|
||||
style="stop-color:#006DFF"
|
||||
offset="0.5562" />
|
||||
<a:midPointStop
|
||||
style="stop-color:#006DFF"
|
||||
offset="0.5" />
|
||||
<a:midPointStop
|
||||
style="stop-color:#0035ED"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
<path
|
||||
d="M 51.083,96.599 C 51.083,100.388 51.083,200.946 51.083,204.734 C 54.933,204.734 202.035,204.734 205.884,204.734 C 205.884,200.946 205.884,100.387 205.884,96.599 C 202.035,96.599 54.933,96.599 51.083,96.599 z "
|
||||
style="fill:url(#XMLID_19_)"
|
||||
id="path76" />
|
||||
<linearGradient
|
||||
x1="128.48441"
|
||||
y1="86.064499"
|
||||
x2="128.48441"
|
||||
y2="228.06689"
|
||||
id="XMLID_20_"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop
|
||||
style="stop-color:#dcf0ff;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop79" />
|
||||
<stop
|
||||
style="stop-color:#428aff;stop-opacity:1"
|
||||
offset="0.6742"
|
||||
id="stop81" />
|
||||
<stop
|
||||
style="stop-color:#006dff;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop83" />
|
||||
<a:midPointStop
|
||||
style="stop-color:#DCF0FF"
|
||||
offset="0" />
|
||||
<a:midPointStop
|
||||
style="stop-color:#DCF0FF"
|
||||
offset="0.5" />
|
||||
<a:midPointStop
|
||||
style="stop-color:#428AFF"
|
||||
offset="0.6742" />
|
||||
<a:midPointStop
|
||||
style="stop-color:#428AFF"
|
||||
offset="0.5" />
|
||||
<a:midPointStop
|
||||
style="stop-color:#006DFF"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
<path
|
||||
d="M 56.083,101.599 C 56.083,110.255 56.083,191.079 56.083,199.734 C 65.135,199.734 191.833,199.734 200.884,199.734 C 200.884,191.079 200.884,110.255 200.884,101.599 C 191.834,101.599 65.135,101.599 56.083,101.599 z "
|
||||
style="fill:url(#XMLID_20_)"
|
||||
id="path85" />
|
||||
<linearGradient
|
||||
x1="54.491199"
|
||||
y1="76.673798"
|
||||
x2="217.155"
|
||||
y2="239.3376"
|
||||
id="XMLID_21_"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop
|
||||
style="stop-color:#0053bd;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop88" />
|
||||
<stop
|
||||
style="stop-color:#00008d;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop90" />
|
||||
<a:midPointStop
|
||||
style="stop-color:#0053BD"
|
||||
offset="0" />
|
||||
<a:midPointStop
|
||||
style="stop-color:#0053BD"
|
||||
offset="0.5" />
|
||||
<a:midPointStop
|
||||
style="stop-color:#00008D"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
<path
|
||||
d="M 207.885,86.599 L 49.083,86.599 C 44.664,86.599 41.083,90.181 41.083,94.599 L 41.083,206.734 C 41.083,211.152 44.664,214.734 49.083,214.734 L 207.884,214.734 C 212.302,214.734 215.884,211.152 215.884,206.734 L 215.884,94.599 C 215.885,90.181 212.303,86.599 207.885,86.599 z M 205.885,204.734 C 202.035,204.734 54.933,204.734 51.084,204.734 C 51.084,200.946 51.084,100.387 51.084,96.599 C 54.934,96.599 202.036,96.599 205.885,96.599 C 205.885,100.388 205.885,200.946 205.885,204.734 z "
|
||||
style="fill:url(#XMLID_21_)"
|
||||
id="path92" />
|
||||
<linearGradient
|
||||
x1="128.48441"
|
||||
y1="86.066902"
|
||||
x2="128.48441"
|
||||
y2="228.0708"
|
||||
id="XMLID_22_"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop95" />
|
||||
<stop
|
||||
style="stop-color:#f7fbff;stop-opacity:1"
|
||||
offset="0.0862"
|
||||
id="stop97" />
|
||||
<stop
|
||||
style="stop-color:#e2eeff;stop-opacity:1"
|
||||
offset="0.2177"
|
||||
id="stop99" />
|
||||
<stop
|
||||
style="stop-color:#c0dbff;stop-opacity:1"
|
||||
offset="0.3779"
|
||||
id="stop101" />
|
||||
<stop
|
||||
style="stop-color:#8fbfff;stop-opacity:1"
|
||||
offset="0.56089997"
|
||||
id="stop103" />
|
||||
<stop
|
||||
style="stop-color:#529cff;stop-opacity:1"
|
||||
offset="0.76310003"
|
||||
id="stop105" />
|
||||
<stop
|
||||
style="stop-color:#0871ff;stop-opacity:1"
|
||||
offset="0.97839999"
|
||||
id="stop107" />
|
||||
<stop
|
||||
style="stop-color:#006dff;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop109" />
|
||||
<a:midPointStop
|
||||
style="stop-color:#FFFFFF"
|
||||
offset="0" />
|
||||
<a:midPointStop
|
||||
style="stop-color:#FFFFFF"
|
||||
offset="0.6158" />
|
||||
<a:midPointStop
|
||||
style="stop-color:#006DFF"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
<path
|
||||
d="M 51.083,96.599 C 51.083,97.141 51.083,99.667 51.083,103.599 C 82.419,103.599 194.529,103.599 197.884,103.599 C 197.884,106.846 197.884,181.163 197.884,204.734 C 202.511,204.734 205.39,204.734 205.884,204.734 C 205.884,200.946 205.884,100.387 205.884,96.599 C 202.035,96.599 54.933,96.599 51.083,96.599 z "
|
||||
style="fill:url(#XMLID_22_)"
|
||||
id="path111" />
|
||||
<path
|
||||
d="M 132.455,30.044 C 126.885,30.044 122.355,34.574 122.355,40.143 L 122.355,158.953 C 122.355,164.521 126.885,169.053 132.455,169.053 L 237.008,169.053 C 242.576,169.053 247.108,164.522 247.108,158.953 L 247.108,40.143 C 247.108,34.574 242.577,30.044 237.008,30.044 L 132.455,30.044 z "
|
||||
style="fill:#003366"
|
||||
id="path113" />
|
||||
<linearGradient
|
||||
x1="158.8916"
|
||||
y1="73.708504"
|
||||
x2="299.68201"
|
||||
y2="214.4994"
|
||||
id="XMLID_23_"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop116" />
|
||||
<stop
|
||||
style="stop-color:#99ccff;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop118" />
|
||||
<a:midPointStop
|
||||
style="stop-color:#FFFFFF"
|
||||
offset="0" />
|
||||
<a:midPointStop
|
||||
style="stop-color:#FFFFFF"
|
||||
offset="0.5" />
|
||||
<a:midPointStop
|
||||
style="stop-color:#99CCFF"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
<path
|
||||
d="M 132.455,35.984 C 130.162,35.984 128.295,37.85 128.295,40.143 L 128.295,158.953 C 128.295,161.246 130.162,163.111 132.455,163.111 L 237.008,163.111 C 239.301,163.111 241.166,161.246 241.166,158.953 L 241.166,40.143 C 241.166,37.85 239.301,35.984 237.008,35.984 L 132.455,35.984 z "
|
||||
style="fill:url(#XMLID_23_)"
|
||||
id="path120" />
|
||||
<path
|
||||
d="M 205.523,86.479 C 216.566,76.124 229.841,71.031 244.136,68.5 L 244.136,40.143 C 244.136,36.206 240.943,33.014 237.007,33.014 L 132.455,33.014 C 128.517,33.014 125.326,36.206 125.326,40.143 L 125.326,125.251 C 154.779,127.473 182.639,106.979 205.523,86.479 z "
|
||||
style="opacity:0.4;fill:#ffffff"
|
||||
id="path122" />
|
||||
<linearGradient
|
||||
x1="141.7061"
|
||||
y1="66.528297"
|
||||
x2="239.2188"
|
||||
y2="164.041"
|
||||
id="XMLID_24_"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop
|
||||
style="stop-color:#0053bd;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop125" />
|
||||
<stop
|
||||
style="stop-color:#00008d;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop127" />
|
||||
<a:midPointStop
|
||||
style="stop-color:#0053BD"
|
||||
offset="0" />
|
||||
<a:midPointStop
|
||||
style="stop-color:#0053BD"
|
||||
offset="0.5" />
|
||||
<a:midPointStop
|
||||
style="stop-color:#00008D"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
<path
|
||||
d="M 207.885,86.599 L 122.355,86.599 L 122.355,96.599 C 162.027,96.599 203.855,96.599 205.885,96.599 C 205.885,98.946 205.885,138.441 205.885,169.053 L 215.885,169.053 L 215.885,94.599 C 215.885,90.181 212.303,86.599 207.885,86.599 z "
|
||||
style="opacity:0.2;fill:url(#XMLID_24_)"
|
||||
id="path129" />
|
||||
<linearGradient
|
||||
x1="164.1201"
|
||||
y1="89.542"
|
||||
x2="164.1201"
|
||||
y2="184.68871"
|
||||
id="XMLID_25_"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop
|
||||
style="stop-color:#c9e6ff;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop132" />
|
||||
<stop
|
||||
style="stop-color:#006dff;stop-opacity:1"
|
||||
offset="0.55620003"
|
||||
id="stop134" />
|
||||
<stop
|
||||
style="stop-color:#0035ed;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop136" />
|
||||
<a:midPointStop
|
||||
style="stop-color:#C9E6FF"
|
||||
offset="0" />
|
||||
<a:midPointStop
|
||||
style="stop-color:#C9E6FF"
|
||||
offset="0.5" />
|
||||
<a:midPointStop
|
||||
style="stop-color:#006DFF"
|
||||
offset="0.5562" />
|
||||
<a:midPointStop
|
||||
style="stop-color:#006DFF"
|
||||
offset="0.5" />
|
||||
<a:midPointStop
|
||||
style="stop-color:#0035ED"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
<path
|
||||
d="M 122.355,158.953 C 122.355,164.521 126.885,169.053 132.455,169.053 L 205.885,169.053 C 205.885,138.442 205.885,98.947 205.885,96.599 C 203.856,96.599 162.028,96.599 122.355,96.599 L 122.355,158.953 L 122.355,158.953 z "
|
||||
style="opacity:0.2;fill:url(#XMLID_25_)"
|
||||
id="path138" />
|
||||
<linearGradient
|
||||
x1="185.8848"
|
||||
y1="86.066902"
|
||||
x2="185.8848"
|
||||
y2="228.0708"
|
||||
id="XMLID_26_"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop
|
||||
style="stop-color:#0053bd;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop141" />
|
||||
<stop
|
||||
style="stop-color:#00008d;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop143" />
|
||||
<a:midPointStop
|
||||
style="stop-color:#0053BD"
|
||||
offset="0" />
|
||||
<a:midPointStop
|
||||
style="stop-color:#0053BD"
|
||||
offset="0.5" />
|
||||
<a:midPointStop
|
||||
style="stop-color:#00008D"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
<path
|
||||
d="M 181.885,96.599 L 181.885,202.734 C 181.885,203.837 180.989,204.734 179.885,204.734 C 184.268,204.734 188.244,204.734 191.705,204.734 C 191.814,204.083 191.885,203.417 191.885,202.734 L 191.885,96.599 C 188.916,96.599 185.557,96.599 181.885,96.599 z "
|
||||
style="opacity:0.3;fill:url(#XMLID_26_)"
|
||||
id="path145" />
|
||||
<path
|
||||
d="M 122.355,96.599 L 122.355,103.599 C 159.458,103.599 195.991,103.599 197.885,103.599 C 197.885,105.771 197.885,139.741 197.885,169.053 L 205.885,169.053 C 205.885,138.442 205.885,98.947 205.885,96.599 C 203.855,96.599 162.027,96.599 122.355,96.599 z "
|
||||
style="opacity:0.2;fill:#ffffff"
|
||||
id="path147" />
|
||||
<rect
|
||||
width="256"
|
||||
height="256"
|
||||
x="0"
|
||||
y="0"
|
||||
style="fill:none"
|
||||
id="_x3C_Slice_x3E_" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 4.1 KiB |
Before Width: | Height: | Size: 4.1 KiB |
Before Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 62 KiB |
Before Width: | Height: | Size: 1.2 KiB |
|
@ -1,679 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
|
||||
<svg
|
||||
width="48pt"
|
||||
height="48pt"
|
||||
viewBox="0 0 48 48"
|
||||
style="overflow:visible;enable-background:new 0 0 48 48"
|
||||
xml:space="preserve"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xap="http://ns.adobe.com/xap/1.0/"
|
||||
xmlns:xapGImg="http://ns.adobe.com/xap/1.0/g/img/"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:xml="http://www.w3.org/XML/1998/namespace"
|
||||
xmlns:xapMM="http://ns.adobe.com/xap/1.0/mm/"
|
||||
xmlns:pdf="http://ns.adobe.com/pdf/1.3/"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
|
||||
xmlns:x="adobe:ns:meta/"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
id="svg589"
|
||||
sodipodi:version="0.32"
|
||||
sodipodi:docname="/home/david/Desktop/temp/devices/gnome-dev-floppy.svg"
|
||||
sodipodi:docbase="/home/david/Desktop/temp/devices/">
|
||||
<defs
|
||||
id="defs677" />
|
||||
<sodipodi:namedview
|
||||
id="base" />
|
||||
<metadata
|
||||
id="metadata590">
|
||||
<xpacket>begin='' id='W5M0MpCehiHzreSzNTczkc9d' </xpacket>
|
||||
<x:xmpmeta
|
||||
x:xmptk="XMP toolkit 3.0-29, framework 1.6">
|
||||
<rdf:RDF>
|
||||
<rdf:Description
|
||||
rdf:about="uuid:9dfcc10e-f4e2-4cbf-91b0-8deea2f1a998">
|
||||
<pdf:Producer>
|
||||
Adobe PDF library 5.00</pdf:Producer>
|
||||
</rdf:Description>
|
||||
<rdf:Description
|
||||
rdf:about="uuid:9dfcc10e-f4e2-4cbf-91b0-8deea2f1a998" />
|
||||
<rdf:Description
|
||||
rdf:about="uuid:9dfcc10e-f4e2-4cbf-91b0-8deea2f1a998" />
|
||||
<rdf:Description
|
||||
rdf:about="uuid:9dfcc10e-f4e2-4cbf-91b0-8deea2f1a998">
|
||||
<xap:CreateDate>
|
||||
2004-02-04T02:08:51+02:00</xap:CreateDate>
|
||||
<xap:ModifyDate>
|
||||
2004-03-29T09:20:16Z</xap:ModifyDate>
|
||||
<xap:CreatorTool>
|
||||
Adobe Illustrator 10.0</xap:CreatorTool>
|
||||
<xap:MetadataDate>
|
||||
2004-02-29T14:54:28+01:00</xap:MetadataDate>
|
||||
<xap:Thumbnails>
|
||||
<rdf:Alt>
|
||||
<rdf:li
|
||||
rdf:parseType="Resource">
|
||||
<xapGImg:format>
|
||||
JPEG</xapGImg:format>
|
||||
<xapGImg:width>
|
||||
256</xapGImg:width>
|
||||
<xapGImg:height>
|
||||
256</xapGImg:height>
|
||||
<xapGImg:image>
|
||||
/9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA
|
||||
AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK
|
||||
DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f
|
||||
Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgBAAEAAwER
|
||||
AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA
|
||||
AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB
|
||||
UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE
|
||||
1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ
|
||||
qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy
|
||||
obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp
|
||||
0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo
|
||||
+DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q7FXYq7FXYq7FXYq7
|
||||
FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7F
|
||||
XYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FX
|
||||
Yq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXY
|
||||
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</xapGImg:image>
|
||||
</rdf:li>
|
||||
</rdf:Alt>
|
||||
</xap:Thumbnails>
|
||||
</rdf:Description>
|
||||
<rdf:Description
|
||||
rdf:about="uuid:9dfcc10e-f4e2-4cbf-91b0-8deea2f1a998">
|
||||
<xapMM:DocumentID>
|
||||
uuid:f3c53255-be8a-4b04-817b-695bf2c54c8b</xapMM:DocumentID>
|
||||
</rdf:Description>
|
||||
<rdf:Description
|
||||
rdf:about="uuid:9dfcc10e-f4e2-4cbf-91b0-8deea2f1a998">
|
||||
<dc:format>
|
||||
image/svg+xml</dc:format>
|
||||
<dc:title>
|
||||
<rdf:Alt>
|
||||
<rdf:li
|
||||
xml:lang="x-default">
|
||||
filesave.ai</rdf:li>
|
||||
</rdf:Alt>
|
||||
</dc:title>
|
||||
</rdf:Description>
|
||||
</rdf:RDF>
|
||||
</x:xmpmeta>
|
||||
<xpacket>end='w' </xpacket>
|
||||
</metadata>
|
||||
<g
|
||||
id="Layer_1">
|
||||
<path
|
||||
style="opacity:0.2;"
|
||||
d="M9.416,5.208c-2.047,0-3.712,1.693-3.712,3.775V39.15c0,2.082,1.666,3.775,3.712,3.775h29.401 c2.047,0,3.712-1.693,3.712-3.775V8.983c0-2.082-1.665-3.775-3.712-3.775H9.416z"
|
||||
id="path592" />
|
||||
<path
|
||||
style="opacity:0.2;"
|
||||
d="M9.041,4.833c-2.047,0-3.712,1.693-3.712,3.775v30.167c0,2.082,1.666,3.775,3.712,3.775h29.401 c2.047,0,3.712-1.693,3.712-3.775V8.608c0-2.082-1.665-3.775-3.712-3.775H9.041z"
|
||||
id="path593" />
|
||||
<path
|
||||
style="fill:#00008D;"
|
||||
d="M8.854,4.646c-2.047,0-3.712,1.693-3.712,3.775v30.167c0,2.082,1.666,3.775,3.712,3.775h29.401 c2.047,0,3.712-1.693,3.712-3.775V8.42c0-2.082-1.665-3.775-3.712-3.775H8.854z"
|
||||
id="path594" />
|
||||
<path
|
||||
style="fill:#00008D;"
|
||||
d="M8.854,5.021c-1.84,0-3.337,1.525-3.337,3.4v30.167c0,1.875,1.497,3.4,3.337,3.4h29.401 c1.84,0,3.337-1.525,3.337-3.4V8.42c0-1.875-1.497-3.4-3.337-3.4H8.854z"
|
||||
id="path595" />
|
||||
<path
|
||||
id="path166_1_"
|
||||
style="fill:#FFFFFF;"
|
||||
d="M40.654,38.588c0,1.36-1.074,2.463-2.399,2.463H8.854c-1.326,0-2.4-1.103-2.4-2.463V8.42 c0-1.36,1.074-2.462,2.4-2.462h29.401c1.325,0,2.399,1.103,2.399,2.462V38.588z" />
|
||||
<linearGradient
|
||||
id="path166_2_"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="-149.0464"
|
||||
y1="251.1436"
|
||||
x2="-149.0464"
|
||||
y2="436.303"
|
||||
gradientTransform="matrix(0.1875 0 0 -0.1875 51.5 83.75)">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#B4E2FF"
|
||||
id="stop598" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#006DFF"
|
||||
id="stop599" />
|
||||
<a:midPointStop
|
||||
offset="0"
|
||||
style="stop-color:#B4E2FF"
|
||||
id="midPointStop600" />
|
||||
<a:midPointStop
|
||||
offset="0.5"
|
||||
style="stop-color:#B4E2FF"
|
||||
id="midPointStop601" />
|
||||
<a:midPointStop
|
||||
offset="1"
|
||||
style="stop-color:#006DFF"
|
||||
id="midPointStop602" />
|
||||
</linearGradient>
|
||||
<path
|
||||
id="path166"
|
||||
style="fill:url(#path166_2_);"
|
||||
d="M40.654,38.588c0,1.36-1.074,2.463-2.399,2.463H8.854c-1.326,0-2.4-1.103-2.4-2.463V8.42 c0-1.36,1.074-2.462,2.4-2.462h29.401c1.325,0,2.399,1.103,2.399,2.462V38.588z" />
|
||||
<path
|
||||
style="fill:#FFFFFF;"
|
||||
d="M8.854,6.521c-1.013,0-1.837,0.852-1.837,1.9v30.167c0,1.048,0.824,1.9,1.837,1.9h29.401 c1.013,0,1.837-0.853,1.837-1.9V8.42c0-1.048-0.824-1.9-1.837-1.9H8.854z"
|
||||
id="path604" />
|
||||
<linearGradient
|
||||
id="XMLID_1_"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="7.3057"
|
||||
y1="7.2559"
|
||||
x2="50.7728"
|
||||
y2="50.7231">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#94CAFF"
|
||||
id="stop606" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#006DFF"
|
||||
id="stop607" />
|
||||
<a:midPointStop
|
||||
offset="0"
|
||||
style="stop-color:#94CAFF"
|
||||
id="midPointStop608" />
|
||||
<a:midPointStop
|
||||
offset="0.5"
|
||||
style="stop-color:#94CAFF"
|
||||
id="midPointStop609" />
|
||||
<a:midPointStop
|
||||
offset="1"
|
||||
style="stop-color:#006DFF"
|
||||
id="midPointStop610" />
|
||||
</linearGradient>
|
||||
<path
|
||||
style="fill:url(#XMLID_1_);"
|
||||
d="M8.854,6.521c-1.013,0-1.837,0.852-1.837,1.9v30.167c0,1.048,0.824,1.9,1.837,1.9h29.401 c1.013,0,1.837-0.853,1.837-1.9V8.42c0-1.048-0.824-1.9-1.837-1.9H8.854z"
|
||||
id="path611" />
|
||||
<linearGradient
|
||||
id="XMLID_2_"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="23.5039"
|
||||
y1="2.187"
|
||||
x2="23.5039"
|
||||
y2="34.4368">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#428AFF"
|
||||
id="stop613" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#C9E6FF"
|
||||
id="stop614" />
|
||||
<a:midPointStop
|
||||
offset="0"
|
||||
style="stop-color:#428AFF"
|
||||
id="midPointStop615" />
|
||||
<a:midPointStop
|
||||
offset="0.5"
|
||||
style="stop-color:#428AFF"
|
||||
id="midPointStop616" />
|
||||
<a:midPointStop
|
||||
offset="1"
|
||||
style="stop-color:#C9E6FF"
|
||||
id="midPointStop617" />
|
||||
</linearGradient>
|
||||
<path
|
||||
style="fill:url(#XMLID_2_);"
|
||||
d="M36.626,6.861c0,0-26.184,0-26.914,0c0,0.704,0,16.59,0,17.294c0.721,0,26.864,0,27.583,0 c0-0.704,0-16.59,0-17.294C36.988,6.861,36.626,6.861,36.626,6.861z"
|
||||
id="path618" />
|
||||
<polygon
|
||||
id="path186_1_"
|
||||
style="fill:#FFFFFF;"
|
||||
points="35.809,6.486 10.221,6.486 10.221,23.405 36.788,23.405 36.788,6.486 " />
|
||||
<linearGradient
|
||||
id="path186_2_"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="-104.5933"
|
||||
y1="411.6699"
|
||||
x2="-206.815"
|
||||
y2="309.4482"
|
||||
gradientTransform="matrix(0.1875 0 0 -0.1875 51.5 83.75)">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#CCCCCC"
|
||||
id="stop621" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#F0F0F0"
|
||||
id="stop622" />
|
||||
<a:midPointStop
|
||||
offset="0"
|
||||
style="stop-color:#CCCCCC"
|
||||
id="midPointStop623" />
|
||||
<a:midPointStop
|
||||
offset="0.5"
|
||||
style="stop-color:#CCCCCC"
|
||||
id="midPointStop624" />
|
||||
<a:midPointStop
|
||||
offset="1"
|
||||
style="stop-color:#F0F0F0"
|
||||
id="midPointStop625" />
|
||||
</linearGradient>
|
||||
<polygon
|
||||
id="path186"
|
||||
style="fill:url(#path186_2_);"
|
||||
points="35.809,6.486 10.221,6.486 10.221,23.405 36.788,23.405 36.788,6.486 " />
|
||||
<path
|
||||
style="fill:#FFFFFF;stroke:#FFFFFF;stroke-width:0.1875;"
|
||||
d="M11.488,7.019c0,0.698,0,14.542,0,15.239c0.716,0,23.417,0,24.133,0c0-0.698,0-14.541,0-15.239 C34.904,7.019,12.204,7.019,11.488,7.019z"
|
||||
id="path627" />
|
||||
<linearGradient
|
||||
id="XMLID_3_"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="34.5967"
|
||||
y1="3.5967"
|
||||
x2="18.4087"
|
||||
y2="19.7847">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#FFFFFF"
|
||||
id="stop629" />
|
||||
<stop
|
||||
offset="0.5506"
|
||||
style="stop-color:#E6EDFF"
|
||||
id="stop630" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#FFFFFF"
|
||||
id="stop631" />
|
||||
<a:midPointStop
|
||||
offset="0"
|
||||
style="stop-color:#FFFFFF"
|
||||
id="midPointStop632" />
|
||||
<a:midPointStop
|
||||
offset="0.5"
|
||||
style="stop-color:#FFFFFF"
|
||||
id="midPointStop633" />
|
||||
<a:midPointStop
|
||||
offset="0.5506"
|
||||
style="stop-color:#E6EDFF"
|
||||
id="midPointStop634" />
|
||||
<a:midPointStop
|
||||
offset="0.5"
|
||||
style="stop-color:#E6EDFF"
|
||||
id="midPointStop635" />
|
||||
<a:midPointStop
|
||||
offset="1"
|
||||
style="stop-color:#FFFFFF"
|
||||
id="midPointStop636" />
|
||||
</linearGradient>
|
||||
<path
|
||||
style="fill:url(#XMLID_3_);stroke:#FFFFFF;stroke-width:0.1875;"
|
||||
d="M11.488,7.019c0,0.698,0,14.542,0,15.239c0.716,0,23.417,0,24.133,0c0-0.698,0-14.541,0-15.239 C34.904,7.019,12.204,7.019,11.488,7.019z"
|
||||
id="path637" />
|
||||
<linearGradient
|
||||
id="path205_1_"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="-174.4409"
|
||||
y1="300.0908"
|
||||
x2="-108.8787"
|
||||
y2="210.2074"
|
||||
gradientTransform="matrix(0.1875 0 0 -0.1875 51.5 83.75)">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#003399"
|
||||
id="stop639" />
|
||||
<stop
|
||||
offset="0.2697"
|
||||
style="stop-color:#0035ED"
|
||||
id="stop640" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#57ADFF"
|
||||
id="stop641" />
|
||||
<a:midPointStop
|
||||
offset="0"
|
||||
style="stop-color:#003399"
|
||||
id="midPointStop642" />
|
||||
<a:midPointStop
|
||||
offset="0.5"
|
||||
style="stop-color:#003399"
|
||||
id="midPointStop643" />
|
||||
<a:midPointStop
|
||||
offset="0.2697"
|
||||
style="stop-color:#0035ED"
|
||||
id="midPointStop644" />
|
||||
<a:midPointStop
|
||||
offset="0.5"
|
||||
style="stop-color:#0035ED"
|
||||
id="midPointStop645" />
|
||||
<a:midPointStop
|
||||
offset="1"
|
||||
style="stop-color:#57ADFF"
|
||||
id="midPointStop646" />
|
||||
</linearGradient>
|
||||
<rect
|
||||
id="path205"
|
||||
x="12.154"
|
||||
y="26.479"
|
||||
style="fill:url(#path205_1_);"
|
||||
width="22.007"
|
||||
height="13.978" />
|
||||
<linearGradient
|
||||
id="XMLID_4_"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="21.8687"
|
||||
y1="25.1875"
|
||||
x2="21.8687"
|
||||
y2="44.6251">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#DFDFDF"
|
||||
id="stop649" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#7D7D99"
|
||||
id="stop650" />
|
||||
<a:midPointStop
|
||||
offset="0"
|
||||
style="stop-color:#DFDFDF"
|
||||
id="midPointStop651" />
|
||||
<a:midPointStop
|
||||
offset="0.5"
|
||||
style="stop-color:#DFDFDF"
|
||||
id="midPointStop652" />
|
||||
<a:midPointStop
|
||||
offset="1"
|
||||
style="stop-color:#7D7D99"
|
||||
id="midPointStop653" />
|
||||
</linearGradient>
|
||||
<path
|
||||
style="fill:url(#XMLID_4_);"
|
||||
d="M13.244,27.021c-0.311,0-0.563,0.252-0.563,0.563v13.104c0,0.312,0.252,0.563,0.563,0.563h17.249 c0.311,0,0.563-0.251,0.563-0.563V27.583c0-0.311-0.252-0.563-0.563-0.563H13.244z M18.85,30.697c0,0.871,0,5.078,0,5.949 c-0.683,0-2.075,0-2.759,0c0-0.871,0-5.078,0-5.949C16.775,30.697,18.167,30.697,18.85,30.697z"
|
||||
id="path654" />
|
||||
<linearGradient
|
||||
id="XMLID_5_"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="-158.0337"
|
||||
y1="288.0684"
|
||||
x2="-158.0337"
|
||||
y2="231.3219"
|
||||
gradientTransform="matrix(0.1875 0 0 -0.1875 51.5 83.75)">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#F0F0F0"
|
||||
id="stop656" />
|
||||
<stop
|
||||
offset="0.6348"
|
||||
style="stop-color:#CECEDB"
|
||||
id="stop657" />
|
||||
<stop
|
||||
offset="0.8595"
|
||||
style="stop-color:#B1B1C5"
|
||||
id="stop658" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#FFFFFF"
|
||||
id="stop659" />
|
||||
<a:midPointStop
|
||||
offset="0"
|
||||
style="stop-color:#F0F0F0"
|
||||
id="midPointStop660" />
|
||||
<a:midPointStop
|
||||
offset="0.5"
|
||||
style="stop-color:#F0F0F0"
|
||||
id="midPointStop661" />
|
||||
<a:midPointStop
|
||||
offset="0.6348"
|
||||
style="stop-color:#CECEDB"
|
||||
id="midPointStop662" />
|
||||
<a:midPointStop
|
||||
offset="0.5"
|
||||
style="stop-color:#CECEDB"
|
||||
id="midPointStop663" />
|
||||
<a:midPointStop
|
||||
offset="0.8595"
|
||||
style="stop-color:#B1B1C5"
|
||||
id="midPointStop664" />
|
||||
<a:midPointStop
|
||||
offset="0.5"
|
||||
style="stop-color:#B1B1C5"
|
||||
id="midPointStop665" />
|
||||
<a:midPointStop
|
||||
offset="1"
|
||||
style="stop-color:#FFFFFF"
|
||||
id="midPointStop666" />
|
||||
</linearGradient>
|
||||
<path
|
||||
style="fill:url(#XMLID_5_);"
|
||||
d="M13.244,27.583v13.104h17.249V27.583H13.244z M19.413,37.209h-3.884v-7.074h3.884V37.209z"
|
||||
id="path667" />
|
||||
<linearGradient
|
||||
id="path228_1_"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="-68.1494"
|
||||
y1="388.4561"
|
||||
x2="-68.1494"
|
||||
y2="404.6693"
|
||||
gradientTransform="matrix(0.1875 0 0 -0.1875 51.5 83.75)">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#3399FF"
|
||||
id="stop669" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#000000"
|
||||
id="stop670" />
|
||||
<a:midPointStop
|
||||
offset="0"
|
||||
style="stop-color:#3399FF"
|
||||
id="midPointStop671" />
|
||||
<a:midPointStop
|
||||
offset="0.5"
|
||||
style="stop-color:#3399FF"
|
||||
id="midPointStop672" />
|
||||
<a:midPointStop
|
||||
offset="1"
|
||||
style="stop-color:#000000"
|
||||
id="midPointStop673" />
|
||||
</linearGradient>
|
||||
<rect
|
||||
id="path228"
|
||||
x="37.83"
|
||||
y="9.031"
|
||||
style="fill:url(#path228_1_);"
|
||||
width="1.784"
|
||||
height="1.785" />
|
||||
<polyline
|
||||
id="_x3C_Slice_x3E_"
|
||||
style="fill:none;"
|
||||
points="0,48 0,0 48,0 48,48 " />
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 1.1 KiB |
|
@ -1,118 +0,0 @@
|
|||
openFile=Open
|
||||
openFileDetail=Open image or label file
|
||||
quit=Quit
|
||||
quitApp=Quit application
|
||||
openDir=Open Dir
|
||||
openDatasetDir=Open DatasetDir
|
||||
copyPrevBounding=Copy previous Bounding Boxes in the current image
|
||||
changeSavedAnnotationDir=Change default saved Annotation dir
|
||||
openAnnotation=Open Annotation
|
||||
openAnnotationDetail=Open an annotation file
|
||||
changeSaveDir=Change Save Dir
|
||||
nextImg=Next Image
|
||||
nextImgDetail=Open the next Image
|
||||
prevImg=Prev Image
|
||||
prevImgDetail=Open the previous Image
|
||||
verifyImg=Verify Image
|
||||
verifyImgDetail=Verify Image
|
||||
save=Check
|
||||
saveDetail=Save the labels to a file
|
||||
changeSaveFormat=Change save format
|
||||
saveAs=Save As
|
||||
saveAsDetail=Save the labels to a different file
|
||||
closeCur=Close
|
||||
closeCurDetail=Close the current file
|
||||
deleteImg=Delete current image
|
||||
deleteImgDetail=Delete the current image
|
||||
resetAll=Reset Interface and Save Dir
|
||||
resetAllDetail=Reset All
|
||||
boxLineColor=Box Line Color
|
||||
boxLineColorDetail=Choose Box line color
|
||||
crtBox=Create RectBox
|
||||
crtBoxDetail=Draw a new box
|
||||
delBox=Delete RectBox
|
||||
delBoxDetail=Remove the box
|
||||
dupBox=Duplicate RectBox
|
||||
dupBoxDetail=Create a duplicate of the selected box
|
||||
tutorial=PaddleOCR url
|
||||
tutorialDetail=Show demo
|
||||
info=Information
|
||||
zoomin=Zoom In
|
||||
zoominDetail=Increase zoom level
|
||||
zoomout=Zoom Out
|
||||
zoomoutDetail=Decrease zoom level
|
||||
originalsize=Original size
|
||||
originalsizeDetail=Zoom to original size
|
||||
fitWin=Fit Window
|
||||
fitWinDetail=Zoom follows window size
|
||||
fitWidth=Fit Width
|
||||
fitWidthDetail=Zoom follows window width
|
||||
editLabel=Edit Label
|
||||
editLabelDetail=Modify the label of the selected Box
|
||||
shapeLineColor=Shape Line Color
|
||||
shapeLineColorDetail=Change the line color for this specific shape
|
||||
shapeFillColor=Shape Fill Color
|
||||
shapeFillColorDetail=Change the fill color for this specific shape
|
||||
showHide=Show/Hide Label Panel
|
||||
useDefaultLabel=Use default label
|
||||
useDifficult=Difficult
|
||||
boxLabelText=Box Labels
|
||||
labels=Labels
|
||||
autoSaveMode=Auto Save mode
|
||||
singleClsMode=Single Class Mode
|
||||
displayLabel=Display Labels
|
||||
displayIndex=Display box index
|
||||
fileList=File List
|
||||
files=Files
|
||||
advancedMode=Advanced Mode
|
||||
advancedModeDetail=Swtich to advanced mode
|
||||
showAllBoxDetail=Show all bounding boxes
|
||||
hideAllBoxDetail=Hide all bounding boxes
|
||||
annoPanel=anno Panel
|
||||
anno=anno
|
||||
addNewBbox=new bbox
|
||||
reLabel=reLabel
|
||||
choosemodel=Choose OCR model
|
||||
tipchoosemodel=Choose OCR model from dir
|
||||
ImageResize=Image Resize
|
||||
IR=Image Resize
|
||||
autoRecognition=Auto Recognition
|
||||
reRecognition=Re-recognition
|
||||
mfile=File
|
||||
medit=Edit
|
||||
mview=View
|
||||
mhelp=Help
|
||||
iconList=Icon List
|
||||
detectionBoxposition=Detection box position
|
||||
recognitionResult=Recognition result
|
||||
creatPolygon=Create PolygonBox
|
||||
rotateLeft=Left turn 90 degrees
|
||||
rotateRight=Right turn 90 degrees
|
||||
drawSquares=Draw Squares
|
||||
saveRec=Export Recognition Result
|
||||
tempLabel=TEMPORARY
|
||||
nullLabel=NULL
|
||||
steps=Steps
|
||||
keys=Shortcut Keys
|
||||
choseModelLg=Choose Model Language
|
||||
cancel=Cancel
|
||||
ok=OK
|
||||
autolabeling=Automatic Labeling
|
||||
hideBox=Hide All Box
|
||||
showBox=Show All Box
|
||||
saveLabel=Export Label
|
||||
singleRe=Re-recognition RectBox
|
||||
labelDialogOption=Pop-up Label Input Dialog
|
||||
undo=Undo
|
||||
undoLastPoint=Undo Last Point
|
||||
autoSaveMode=Auto Export Label Mode
|
||||
lockBox=Lock selected box/Unlock all box
|
||||
lockBoxDetail=Lock selected box/Unlock all box
|
||||
keyListTitle=Key List
|
||||
keyDialogTip=Enter object label
|
||||
keyChange=Change Box Key
|
||||
TableRecognition=Table Recognition
|
||||
cellreRecognition=Cell Re-Recognition
|
||||
exportJSON=Export Table Label
|
||||
expandBox=Expand Box
|
||||
expandBoxDetail=Expand Box
|
|
@ -1,118 +0,0 @@
|
|||
saveAsDetail=將标签保存到其他文件
|
||||
changeSaveDir=改变存放目录
|
||||
openFile=打开文件
|
||||
shapeLineColorDetail=更改线条颜色
|
||||
resetAll=重置界面与保存地址
|
||||
crtBox=矩形标注
|
||||
crtBoxDetail=创建一个新的区块
|
||||
dupBoxDetail=复制区块
|
||||
verifyImg=验证图像
|
||||
zoominDetail=放大
|
||||
verifyImgDetail=验证图像
|
||||
saveDetail=保存标签文件
|
||||
openFileDetail=打开图像文件
|
||||
fitWidthDetail=调整宽度适应到窗口宽度
|
||||
tutorial=PaddleOCR地址
|
||||
editLabel=编辑标签
|
||||
openAnnotationDetail=打开标签文件
|
||||
quit=退出
|
||||
shapeFillColorDetail=更改填充颜色
|
||||
closeCurDetail=关闭当前文件
|
||||
closeCur=关闭文件
|
||||
deleteImg=删除图像
|
||||
deleteImgDetail=删除当前图像
|
||||
fitWin=调整到窗口大小
|
||||
delBox=删除选择的区块
|
||||
boxLineColorDetail=选择线框颜色
|
||||
originalsize=原始大小
|
||||
resetAllDetail=重置所有设定
|
||||
zoomoutDetail=放大画面
|
||||
save=确认
|
||||
saveAs=另存为
|
||||
fitWinDetail=缩放到当前窗口大小
|
||||
openDir=打开目录
|
||||
openDatasetDir=打开数据集路径
|
||||
copyPrevBounding=复制当前图像中的上一个边界框
|
||||
showHide=显示/隐藏标签
|
||||
changeSaveFormat=更改存储格式
|
||||
shapeFillColor=填充颜色
|
||||
quitApp=退出程序
|
||||
dupBox=复制区块
|
||||
delBoxDetail=删除区块
|
||||
zoomin=放大画面
|
||||
info=信息
|
||||
openAnnotation=开启标签
|
||||
prevImgDetail=上一个图像
|
||||
fitWidth=缩放到当前画面宽度
|
||||
zoomout=缩小画面
|
||||
changeSavedAnnotationDir=更改保存标签文件的预设目录
|
||||
nextImgDetail=下一个图像
|
||||
originalsizeDetail=放大到原始大小
|
||||
prevImg=上一张
|
||||
tutorialDetail=显示示范内容
|
||||
shapeLineColor=形状线条颜色
|
||||
boxLineColor=区块线条颜色
|
||||
editLabelDetail=修改当前所选的区块颜色
|
||||
nextImg=下一张
|
||||
useDefaultLabel=使用预设标签
|
||||
useDifficult=有难度的
|
||||
boxLabelText=区块的标签
|
||||
labels=标签
|
||||
autoSaveMode=自动保存模式
|
||||
singleClsMode=单一类别模式
|
||||
displayLabel=显示类别
|
||||
displayIndex=显示box序号
|
||||
fileList=文件列表
|
||||
files=文件
|
||||
advancedMode=专家模式
|
||||
advancedModeDetail=切换到专家模式
|
||||
showAllBoxDetail=显示所有区块
|
||||
hideAllBoxDetail=隐藏所有区块
|
||||
annoPanel=标注面板
|
||||
anno=标注
|
||||
addNewBbox=新框
|
||||
reLabel=重标注
|
||||
choosemodel=选择模型
|
||||
tipchoosemodel=选择OCR模型
|
||||
ImageResize=图片缩放
|
||||
IR=图片缩放
|
||||
autoRecognition=自动标注
|
||||
reRecognition=重新识别
|
||||
mfile=文件
|
||||
medit=编辑
|
||||
mview=视图
|
||||
mhelp=帮助
|
||||
iconList=缩略图
|
||||
detectionBoxposition=检测框位置
|
||||
recognitionResult=识别结果
|
||||
creatPolygon=多点标注
|
||||
drawSquares=正方形标注
|
||||
rotateLeft=图片左旋转90度
|
||||
rotateRight=图片右旋转90度
|
||||
saveRec=导出识别结果
|
||||
tempLabel=待识别
|
||||
nullLabel=无法识别
|
||||
steps=操作步骤
|
||||
keys=快捷键
|
||||
choseModelLg=选择模型语言
|
||||
cancel=取消
|
||||
ok=确认
|
||||
autolabeling=自动标注中
|
||||
hideBox=隐藏所有标注
|
||||
showBox=显示所有标注
|
||||
saveLabel=导出标记结果
|
||||
singleRe=重识别此区块
|
||||
labelDialogOption=弹出标记输入框
|
||||
undo=撤销
|
||||
undoLastPoint=撤销上个点
|
||||
autoSaveMode=自动导出标记结果
|
||||
lockBox=锁定框/解除锁定框
|
||||
lockBoxDetail=若当前没有框处于锁定状态则锁定选中的框,若存在锁定框则解除所有锁定框的锁定状态
|
||||
keyListTitle=关键词列表
|
||||
keyDialogTip=请输入类型名称
|
||||
keyChange=更改Box关键字类别
|
||||
TableRecognition=表格识别
|
||||
cellreRecognition=单元格重识别
|
||||
exportJSON=导出表格标注
|
||||
expandBox=扩大框
|
||||
expandBoxDetail=扩大所选框
|
|
@ -1,8 +0,0 @@
|
|||
[bumpversion]
|
||||
commit = True
|
||||
tag = True
|
||||
|
||||
[bumpversion:file:setup.py]
|
||||
|
||||
[bdist_wheel]
|
||||
universal = 1
|
|
@ -1,55 +0,0 @@
|
|||
# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from setuptools import setup
|
||||
from io import open
|
||||
|
||||
with open("requirements.txt", encoding="utf-8-sig") as f:
|
||||
requirements = f.readlines()
|
||||
requirements.append("tqdm")
|
||||
|
||||
|
||||
def readme():
|
||||
with open("README.md", encoding="utf-8-sig") as f:
|
||||
README = f.read()
|
||||
return README
|
||||
|
||||
|
||||
setup(
|
||||
name="PPOCRLabel",
|
||||
packages=["PPOCRLabel"],
|
||||
package_data={"PPOCRLabel": ["libs/*", "resources/strings/*", "resources/icons/*"]},
|
||||
package_dir={"PPOCRLabel": ""},
|
||||
include_package_data=True,
|
||||
entry_points={"console_scripts": ["PPOCRLabel= PPOCRLabel.PPOCRLabel:main"]},
|
||||
version="2.1.3",
|
||||
install_requires=requirements,
|
||||
license="Apache License 2.0",
|
||||
description="PPOCRLabelv2 is a semi-automatic graphic annotation tool suitable for OCR field, with built-in PP-OCR model to automatically detect and re-recognize data. It is written in Python3 and PyQT5, supporting rectangular box, table, irregular text and key information annotation modes. Annotations can be directly used for the training of PP-OCR detection and recognition models.",
|
||||
long_description=readme(),
|
||||
long_description_content_type="text/markdown",
|
||||
url="https://github.com/PaddlePaddle/PaddleOCR",
|
||||
download_url="https://github.com/PaddlePaddle/PaddleOCR.git",
|
||||
keywords=[
|
||||
"ocr textdetection textrecognition paddleocr crnn east star-net rosetta ocrlite db chineseocr chinesetextdetection chinesetextrecognition"
|
||||
],
|
||||
classifiers=[
|
||||
"Intended Audience :: Developers",
|
||||
"Operating System :: OS Independent",
|
||||
"Natural Language :: English",
|
||||
"Programming Language :: Python :: 3.6",
|
||||
"Programming Language :: Python :: 3.7",
|
||||
"Topic :: Utilities",
|
||||
],
|
||||
)
|
|
@ -158,7 +158,7 @@ PaddleOCR旨在打造一套丰富、领先、且实用的OCR工具库,助力
|
|||
- [使用PaddleOCR架构添加新算法](./doc/doc_ch/add_new_algorithm.md)
|
||||
- [场景应用](./applications)
|
||||
- 数据标注与合成
|
||||
- [半自动标注工具PPOCRLabel](./PPOCRLabel/README_ch.md)
|
||||
- [半自动标注工具PPOCRLabel](https://github.com/PFCCLab/PPOCRLabel/blob/main/README_ch.md)
|
||||
- [数据合成工具Style-Text](./StyleText/README_ch.md)
|
||||
- [其它数据标注工具](./doc/doc_ch/data_annotation.md)
|
||||
- [其它数据合成工具](./doc/doc_ch/data_synthesis.md)
|
||||
|
|
|
@ -46,7 +46,7 @@ PaddleOCR旨在打造一套丰富、领先、且实用的OCR工具库,助力
|
|||
|
||||
- **2022.5.9 发布 PaddleOCR [release/2.5](https://github.com/PaddlePaddle/PaddleOCR/tree/release/2.5)**
|
||||
- 发布[PP-OCRv3](./doc/doc_ch/ppocr_introduction.md#pp-ocrv3),速度可比情况下,中文场景效果相比于PP-OCRv2再提升5%,英文场景提升11%,80语种多语言模型平均识别准确率提升5%以上;
|
||||
- 发布半自动标注工具[PPOCRLabelv2](./PPOCRLabel):新增表格文字图像、图像关键信息抽取任务和不规则文字图像的标注功能;
|
||||
- 发布半自动标注工具[PPOCRLabelv2](https://github.com/PFCCLab/PPOCRLabel):新增表格文字图像、图像关键信息抽取任务和不规则文字图像的标注功能;
|
||||
- 发布OCR产业落地工具集:打通22种训练部署软硬件环境与方式,覆盖企业90%的训练部署环境需求;
|
||||
- 发布交互式OCR开源电子书[《动手学OCR》](./doc/doc_ch/ocr_book.md),覆盖OCR全栈技术的前沿理论与代码实践,并配套教学视频。
|
||||
|
||||
|
@ -153,7 +153,7 @@ PaddleOCR旨在打造一套丰富、领先、且实用的OCR工具库,助力
|
|||
- [使用PaddleOCR架构添加新算法](./doc/doc_ch/add_new_algorithm.md)
|
||||
- [场景应用](./applications)
|
||||
- 数据标注与合成
|
||||
- [半自动标注工具PPOCRLabel](./PPOCRLabel/README_ch.md)
|
||||
- [半自动标注工具PPOCRLabel](https://github.com/PFCCLab/PPOCRLabel/blob/main/README_ch.md)
|
||||
- [数据合成工具Style-Text](./StyleText/README_ch.md)
|
||||
- [其它数据标注工具](./doc/doc_ch/data_annotation.md)
|
||||
- [其它数据合成工具](./doc/doc_ch/data_synthesis.md)
|
||||
|
|
|
@ -50,7 +50,7 @@ PaddleOCR aims to create multilingual, awesome, leading, and practical OCR tools
|
|||
- Table Recognition: [TableMaster](doc/doc_en/algorithm_table_master_en.md)
|
||||
- **2022.5.9 Release PaddleOCR [release/2.5](https://github.com/PaddlePaddle/PaddleOCR/tree/release/2.5)**
|
||||
- Release [PP-OCRv3](./doc/doc_en/ppocr_introduction_en.md#pp-ocrv3): With comparable speed, the effect of Chinese scene is further improved by 5% compared with PP-OCRv2, the effect of English scene is improved by 11%, and the average recognition accuracy of 80 language multilingual models is improved by more than 5%.
|
||||
- Release [PPOCRLabelv2](./PPOCRLabel): Add the annotation function for table recognition task, key information extraction task and irregular text image.
|
||||
- Release [PPOCRLabelv2](https://github.com/PFCCLab/PPOCRLabel): Add the annotation function for table recognition task, key information extraction task and irregular text image.
|
||||
- Release interactive e-book [*"Dive into OCR"*](./doc/doc_en/ocr_book_en.md), covers the cutting-edge theory and code practice of OCR full stack technology.
|
||||
- [more](./doc/doc_en/update_en.md)
|
||||
|
||||
|
@ -163,7 +163,7 @@ Scan the QR code below on WeChat to add operation students, and reply [paddlex],
|
|||
- [Key Information Extraction](./doc/doc_en/algorithm_overview_en.md)
|
||||
- [Add New Algorithms to PaddleOCR](./doc/doc_en/add_new_algorithm_en.md)
|
||||
- Data Annotation and Synthesis
|
||||
- [Semi-automatic Annotation Tool: PPOCRLabel](./PPOCRLabel/README.md)
|
||||
- [Semi-automatic Annotation Tool: PPOCRLabel](https://github.com/PFCCLab/PPOCRLabel/blob/main/README.md)
|
||||
- [Data Synthesis Tool: Style-Text](./StyleText/README.md)
|
||||
- [Other Data Annotation Tools](./doc/doc_en/data_annotation_en.md)
|
||||
- [Other Data Synthesis Tools](./doc/doc_en/data_synthesis_en.md)
|
||||
|
|
|
@ -140,11 +140,11 @@ python3 main.py \
|
|||
|
||||
使用[爬虫工具](https://github.com/Joeclinton1/google-images-download.git)获得无标注数据
|
||||
|
||||
2. [PPOCRLabel](https://github.com/PaddlePaddle/PaddleOCR/tree/release/2.5/PPOCRLabel) 完成半自动标注
|
||||
2. [PPOCRLabel](https://github.com/PFCCLab/PPOCRLabel) 完成半自动标注
|
||||
|
||||
PPOCRLabel是一款适用于OCR领域的半自动化图形标注工具,内置PP-OCR模型对数据自动标注和重新识别。使用Python3和PyQT5编写,支持矩形框标注、表格标注、不规则文本标注、关键信息标注模式,导出格式可直接用于PaddleOCR检测和识别模型的训练。
|
||||
|
||||

|
||||

|
||||
|
||||
|
||||
收集完数据后就可以进行分配了,验证集中一般都是真实数据,训练集中包含合成数据+真实数据。本例中标注了155张图片,其中训练集和验证集的数目为100和55。
|
||||
|
|
|
@ -73,10 +73,10 @@
|
|||
|
||||
## 3.1 数据标注
|
||||
|
||||
本项目中使用[PPOCRLabel](https://github.com/PaddlePaddle/PaddleOCR/tree/release/2.6/PPOCRLabel)工具标注印章检测数据,标注内容包括印章的位置以及印章中文字的位置和文字内容。
|
||||
本项目中使用[PPOCRLabel](https://github.com/PFCCLab/PPOCRLabel)工具标注印章检测数据,标注内容包括印章的位置以及印章中文字的位置和文字内容。
|
||||
|
||||
|
||||
注:PPOCRLabel的使用方法参考[文档](https://github.com/PaddlePaddle/PaddleOCR/tree/release/2.6/PPOCRLabel)。
|
||||
注:PPOCRLabel的使用方法参考[文档](https://github.com/PFCCLab/PPOCRLabel)。
|
||||
|
||||
PPOCRlabel标注印章数据步骤:
|
||||
- 打开数据集所在文件夹
|
||||
|
|
|
@ -107,7 +107,7 @@ HEADER
|
|||
|
||||
更多关于公开数据集的介绍,请参考[关键信息抽取数据集说明文档](./dataset/kie_datasets.md)。
|
||||
|
||||
PaddleOCR也支持了关键信息抽取模型的标注,具体使用方法请参考:[PPOCRLabel使用文档](../../PPOCRLabel/README_ch.md)。
|
||||
PaddleOCR也支持了关键信息抽取模型的标注,具体使用方法请参考:[PPOCRLabel使用文档](https://github.com/PFCCLab/PPOCRLabel/blob/main/README_ch.md)。
|
||||
|
||||
|
||||
# 2. 开始训练
|
||||
|
|
|
@ -81,7 +81,7 @@ TableGeneration是一个开源表格数据集生成工具,其通过浏览器
|
|||
|
||||
## 1.4 数据标注
|
||||
|
||||
数据标注可参考[PPOCRLabel](../../PPOCRLabel/README_ch.md)
|
||||
数据标注可参考[PPOCRLabel](https://github.com/PFCCLab/PPOCRLabel/blob/main/README_ch.md)
|
||||
|
||||
# 2. 开始训练
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# 更新
|
||||
- 2022.5.9 发布PaddleOCR v2.5。发布内容包括:
|
||||
- [PP-OCRv3](./ppocr_introduction.md#pp-ocrv3),速度可比情况下,中文场景效果相比于PP-OCRv2再提升5%,英文场景提升11%,80语种多语言模型平均识别准确率提升5%以上;
|
||||
- 半自动标注工具[PPOCRLabelv2](../../PPOCRLabel):新增表格文字图像、图像关键信息抽取任务和不规则文字图像的标注功能;
|
||||
- 半自动标注工具[PPOCRLabelv2](https://github.com/PFCCLab/PPOCRLabel):新增表格文字图像、图像关键信息抽取任务和不规则文字图像的标注功能;
|
||||
- OCR产业落地工具集:打通22种训练部署软硬件环境与方式,覆盖企业90%的训练部署环境需求
|
||||
- 交互式OCR开源电子书[《动手学OCR》](./ocr_book.md),覆盖OCR全栈技术的前沿理论与代码实践,并配套教学视频。
|
||||
- 2022.5.7 添加对[Weights & Biases](https://docs.wandb.ai/)训练日志记录工具的支持。
|
||||
|
@ -13,7 +13,7 @@
|
|||
- 2021.4.8 release 2.1版本,新增AAAI 2021论文[端到端识别算法PGNet](https://github.com/PaddlePaddle/PaddleOCR/blob/release/2.2/doc/doc_ch/pgnet.md)开源,[多语言模型](https://github.com/PaddlePaddle/PaddleOCR/blob/release/2.2/doc/doc_ch/multi_languages.md)支持种类增加到80+。
|
||||
- 2020.12.15 更新数据合成工具[Style-Text](../../StyleText/README_ch.md),可以批量合成大量与目标场景类似的图像,在多个场景验证,效果明显提升。
|
||||
- 2020.12.07 [FAQ](../../doc/doc_ch/FAQ.md)新增5个高频问题,总数124个,并且计划以后每周一都会更新,欢迎大家持续关注。
|
||||
- 2020.11.25 更新半自动标注工具[PPOCRLabel](../../PPOCRLabel/README_ch.md),辅助开发者高效完成标注任务,输出格式与PP-OCR训练任务完美衔接。
|
||||
- 2020.11.25 更新半自动标注工具[PPOCRLabel](https://github.com/PFCCLab/PPOCRLabel/blob/main/README_ch.md),辅助开发者高效完成标注任务,输出格式与PP-OCR训练任务完美衔接。
|
||||
- 2020.9.22 更新PP-OCR技术文章,https://arxiv.org/abs/2009.09941
|
||||
- 2020.9.19 更新超轻量压缩ppocr_mobile_slim系列模型,整体模型3.5M(详见PP-OCR Pipeline),适合在移动端部署使用。
|
||||
- 2020.9.17 更新超轻量ppocr_mobile系列和通用ppocr_server系列中英文ocr模型,媲美商业效果。
|
||||
|
|
|
@ -113,7 +113,7 @@ If you do not have local dataset, you can donwload the source files of [XFUND](h
|
|||
|
||||
For more information about public KIE datasets, please refer to [KIE dataset tutorial](./dataset/kie_datasets_en.md).
|
||||
|
||||
PaddleOCR also supports the annotation of KIE models. Please refer to [PPOCRLabel tutorial](../../PPOCRLabel/README.md).
|
||||
PaddleOCR also supports the annotation of KIE models. Please refer to [PPOCRLabel tutorial](https://github.com/PFCCLab/PPOCRLabel/blob/main/README.md).
|
||||
|
||||
# 2. Training
|
||||
|
||||
|
|
|
@ -83,7 +83,7 @@ Some samples are as follows:
|
|||
|
||||
## 1.4 Data annotation
|
||||
|
||||
Data annotation can refer to[PPOCRLabel](../../PPOCRLabel/README.md)
|
||||
Data annotation can refer to[PPOCRLabel](https://github.com/PFCCLab/PPOCRLabel/blob/main/README.md)
|
||||
|
||||
# 2. Training
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# RECENT UPDATES
|
||||
- 2022.5.9 release PaddleOCR v2.5, including:
|
||||
- [PP-OCRv3](./ppocr_introduction_en.md#pp-ocrv3): With comparable speed, the effect of Chinese scene is further improved by 5% compared with PP-OCRv2, the effect of English scene is improved by 11%, and the average recognition accuracy of 80 language multilingual models is improved by more than 5%.
|
||||
- [PPOCRLabelv2](../../PPOCRLabel): Add the annotation function for table recognition task, key information extraction task and irregular text image.
|
||||
- [PPOCRLabelv2](https://github.com/PFCCLab/PPOCRLabel/blob/main/README.md): Add the annotation function for table recognition task, key information extraction task and irregular text image.
|
||||
- Interactive e-book [*"Dive into OCR"*](./ocr_book_en.md), covers the cutting-edge theory and code practice of OCR full stack technology.
|
||||
- 2022.5.7 Add support for metric and model logging during training to [Weights & Biases](https://docs.wandb.ai/).
|
||||
- 2021.12.21 OCR open source online course starts. The lesson starts at 8:30 every night and lasts for ten days. Free registration: https://aistudio.baidu.com/aistudio/course/introduce/25207
|
||||
|
@ -12,7 +12,7 @@
|
|||
|
||||
- 2021.1.21 update more than 25+ multilingual recognition models [models list](./models_list_en.md), including:English, Chinese, German, French, Japanese,Spanish,Portuguese Russia Arabic and so on. Models for more languages will continue to be updated [Develop Plan](https://github.com/PaddlePaddle/PaddleOCR/issues/1048).
|
||||
- 2020.12.15 update Data synthesis tool, i.e., [Style-Text](../../StyleText/README.md),easy to synthesize a large number of images which are similar to the target scene image.
|
||||
- 2020.11.25 Update a new data annotation tool, i.e., [PPOCRLabel](../../PPOCRLabel/README.md), which is helpful to improve the labeling efficiency. Moreover, the labeling results can be used in training of the PP-OCR system directly.
|
||||
- 2020.11.25 Update a new data annotation tool, i.e., [PPOCRLabel](https://github.com/PFCCLab/PPOCRLabel/blob/main/README.md), which is helpful to improve the labeling efficiency. Moreover, the labeling results can be used in training of the PP-OCR system directly.
|
||||
- 2020.9.22 Update the PP-OCR technical article, https://arxiv.org/abs/2009.09941
|
||||
- 2020.9.19 Update the ultra lightweight compressed ppocr_mobile_slim series models, the overall model size is 3.5M, suitable for mobile deployment.
|
||||
- 2020.9.17 update English recognition model and Multilingual recognition model, `English`, `Chinese`, `German`, `French`, `Japanese` and `Korean` have been supported. Models for more languages will continue to be updated.
|
||||
|
|
|
@ -44,7 +44,7 @@ PaddleOCR стремится создавать многоязычные, пот
|
|||
- Выпуск **9 вертикальных моделей**, таких как цифровая трубка, ЖК-экран, номерной знак, модель распознавания рукописного ввода, высокоточная модель SVTR и т. д., охватывающих основные вертикальные приложения OCR в целом, производственной, финансовой и транспортной отраслях.
|
||||
- **🔥2022.5.9 Выпуск PaddleOCR [Выпуск /2.5](https://github.com/PaddlePaddle/PaddleOCR/tree/release/2.5)**
|
||||
- Выпускать [PP-OCRv3](../doc_en/ppocr_introduction_en.md#pp-ocrv3): При сопоставимой скорости эффект китайской сцены улучшен на 5% по сравнению с ПП-OCRRv2, эффект английской сцены улучшен на 11%, а средняя точность распознавания 80 языковых многоязычных моделей улучшена более чем на 5%.
|
||||
- Выпускать [PPOCRLabelv2](./PPOCRLabel): Добавьте функцию аннотации для задачи распознавания таблиц, задачи извлечения ключевой информации и изображения неправильного текста.
|
||||
- Выпускать [PPOCRLabelv2](https://github.com/PFCCLab/PPOCRLabel/blob/main/README.md): Добавьте функцию аннотации для задачи распознавания таблиц, задачи извлечения ключевой информации и изображения неправильного текста.
|
||||
- Выпустить интерактивную электронную книгу [*"Погружение в OCR"*](../doc_en/ocr_book_en.md), охватывает передовую теорию и практику кодирования технологии полного стека OCR.
|
||||
- [подробнее](../doc_en/update_en.md)
|
||||
|
||||
|
@ -139,7 +139,7 @@ paddleocr --image_dir /your/test/image.jpg --lang=ru
|
|||
- [Извлечение ключевой информации](../doc_en/algorithm_overview_en.md)
|
||||
- [Добавьте новые алгоритмы в PaddleOCR](../doc_en/add_new_algorithm_en.md)
|
||||
- Аннотации и синтез данных
|
||||
- [Полуавтоматический инструмент аннотации данных: метка ППOCRR](./PPOCRLabel/README.md)
|
||||
- [Полуавтоматический инструмент аннотации данных: метка ППOCRR](https://github.com/PFCCLab/PPOCRLabel/blob/main/README.md)
|
||||
- [Инструмент синтеза данных: Стиль-текст](./StyleText/README.md)
|
||||
- [Другие инструменты аннотирования данных](../doc_en/data_annotation_en.md)
|
||||
- [Другие инструменты синтеза данных](../doc_en/data_synthesis_en.md)
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
|
||||
- **🔥2022.5.9 रिलीज Paddleओसीआर [रिलीज/2.5](https://github.com/PaddlePaddle/Paddleओसीआर/tree/release/2.5)**
|
||||
- रिलीज [PP-OCRv3](../doc_en/ppocr_introduction_en.md#pp-ocrv3): तुलनात्मक स्पीड के साथ, चाइनीज शीन्स का प्रभाव PP-ओसीआर v2 की तुलना में 5% की और वृद्धि हुयी है इंगलिस शीन्स के प्रभाव में 11% का सुधार हुआ है, और 80 भाषाओं के बहुभाषी मॉडलों की औसत पहचान सटीकता में 5% से अधिक सुधार हुआ है।
|
||||
- रिलीज़ [PPOCRLabelv2](./PPOCRLabel): टेबल टेबल रिकोगनाइजेशन टास्क की इंफॉर्मेशन एक्स्ट्रेक्शन टास्क और अनियमित टेक्सट इमेज के लिए एनोटेशन फ़ंक्शन एड करे।
|
||||
- रिलीज़ [PPOCRLabelv2](https://github.com/PFCCLab/PPOCRLabel/blob/main/README.md): टेबल टेबल रिकोगनाइजेशन टास्क की इंफॉर्मेशन एक्स्ट्रेक्शन टास्क और अनियमित टेक्सट इमेज के लिए एनोटेशन फ़ंक्शन एड करे।
|
||||
|
||||
- इंटरएक्टिव ई-बुक जारी करें [*"ओसीआर में गोता लगाएँ"*](../doc_en/ocr_book_en.md), ओसीआर पूर्ण स्टैक तकनीक के अत्याधुनिक सिद्धांत और कोड प्रेक्टिस को कवर करता है।
|
||||
|
||||
|
@ -136,7 +136,7 @@ paddleocr --image_dir /your/test/image.jpg --lang=hi
|
|||
- [की इंफॉर्मेशन एक्स्ट्रेक्शन](../doc_en/algorithm_overview_en.md)
|
||||
- [पैडलओसीआर में नए एल्गोरिदम जोड़ें](../doc_en/add_new_algorithm_en.md)
|
||||
- डेटा एनोटेशन और सिंथेसिस
|
||||
- [सेमी-ऑटोमैटिक एनोटेशन टूल: PPओसीआरलेबल](./PPOCRLabel/README.md)
|
||||
- [सेमी-ऑटोमैटिक एनोटेशन टूल: PPओसीआरलेबल](https://github.com/PFCCLab/PPOCRLabel/blob/main/README.md)
|
||||
- [डेटा सिंथेसिस टूल: स्टाइल-टेक्सट](./StyleText/README.md)
|
||||
- [अन्य डेटा एनोटेशन टूल](../doc_en/data_annotation_en.md)
|
||||
- [अन्य डेटा सिंथेसिस टूल](../doc_en/data_synthesis_en.md)
|
||||
|
|