diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml new file mode 100644 index 0000000..1966567 --- /dev/null +++ b/.gitea/workflows/build.yaml @@ -0,0 +1,47 @@ +name: Build +run-name: ${{ github.actor }} is upgrade release ๐Ÿš€ +on: [push] +env: + REPOSITORY: ${{ github.repository }} + COMMIT_ID: ${{ github.sha }} +jobs: + Build-Deploy-Actions: + runs-on: ubuntu-latest + steps: + - run: echo "๐ŸŽ‰ The job was automatically triggered by a ${{ github.event_name }} event." + - run: echo "๐Ÿง This job is now running on a ${{ runner.os }} server hosted by Gitea!" + - run: echo "๐Ÿ”Ž The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}." + - name: Check out repository code + uses: actions/checkout@v3 + - + name: Setup Git LFS + run: | + git lfs install + git lfs fetch + git lfs checkout + - name: List files in the repository + run: | + ls ${{ github.workspace }} + - + name: Docker Image Info + id: image-info + run: | + echo "::set-output name=image_name::$(echo $REPOSITORY | tr '[:upper:]' '[:lower:]')" + echo "::set-output name=image_tag::${COMMIT_ID:0:10}" + - + name: Login to Docker Hub + uses: docker/login-action@v2 + with: + registry: artifacts.iflytek.com + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + - + name: Build and push + run: | + docker version + docker buildx build -t artifacts.iflytek.com/docker-private/atp/${{ steps.image-info.outputs.image_name }}:${{ steps.image-info.outputs.image_tag }} . --file ${{ github.workspace }}/Dockerfile --load + docker push artifacts.iflytek.com/docker-private/atp/${{ steps.image-info.outputs.image_name }}:${{ steps.image-info.outputs.image_tag }} + docker rmi artifacts.iflytek.com/docker-private/atp/${{ steps.image-info.outputs.image_name }}:${{ steps.image-info.outputs.image_tag }} + - run: echo "๐Ÿ This job's status is ${{ job.status }}." diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..823de7a --- /dev/null +++ b/Dockerfile @@ -0,0 +1,13 @@ +FROM python:3.7.4-slim + +WORKDIR /app + +COPY requirements.txt /app + +RUN pip config set global.index-url https://pypi.mirrors.ustc.edu.cn/simple/ + +RUN pip3 install --trusted-host pypi.python.org -r requirements.txt + +COPY . /app + +CMD ["python", "app.py"] diff --git a/app.py b/app.py new file mode 100644 index 0000000..730a3be --- /dev/null +++ b/app.py @@ -0,0 +1,126 @@ +from transformers import DetrFeatureExtractor, DetrForObjectDetection +from PIL import Image +import requests +from torch import nn +from gradio.themes.utils import sizes +import torch +import matplotlib.pyplot as plt +import math +import gradio as gr +import torchvision.transforms as T +import io + + +theme = gr.themes.Default(radius_size=sizes.radius_none).set( + block_label_text_color = '#4D63FF', + block_title_text_color = '#4D63FF', + button_primary_text_color = '#4D63FF', + button_primary_background_fill='#FFFFFF', + button_primary_border_color='#4D63FF', + button_primary_background_fill_hover='#EDEFFF', +) + + +# COCO classes +CLASSES = [ + 'N/A', 'person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', + 'train', 'truck', 'boat', 'traffic light', 'fire hydrant', 'N/A', + 'stop sign', 'parking meter', 'bench', 'bird', 'cat', 'dog', 'horse', + 'sheep', 'cow', 'elephant', 'bear', 'zebra', 'giraffe', 'N/A', 'backpack', + 'umbrella', 'N/A', 'N/A', 'handbag', 'tie', 'suitcase', 'frisbee', 'skis', + 'snowboard', 'sports ball', 'kite', 'baseball bat', 'baseball glove', + 'skateboard', 'surfboard', 'tennis racket', 'bottle', 'N/A', 'wine glass', + 'cup', 'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple', 'sandwich', + 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza', 'donut', 'cake', + 'chair', 'couch', 'potted plant', 'bed', 'N/A', 'dining table', 'N/A', + 'N/A', 'toilet', 'N/A', 'tv', 'laptop', 'mouse', 'remote', 'keyboard', + 'cell phone', 'microwave', 'oven', 'toaster', 'sink', 'refrigerator', 'N/A', + 'book', 'clock', 'vase', 'scissors', 'teddy bear', 'hair drier', + 'toothbrush' +] + +# colors for visualization +COLORS = [[0.000, 0.447, 0.741], [0.850, 0.325, 0.098], [0.929, 0.694, 0.125], + [0.494, 0.184, 0.556], [0.466, 0.674, 0.188], [0.301, 0.745, 0.933]] + + +# standard PyTorch mean-std input image normalization +transform = T.Compose([ + T.Resize(800), + T.ToTensor(), + T.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) +]) + +# for output bounding box post-processing +def box_cxcywh_to_xyxy(x): + x_c, y_c, w, h = x.unbind(1) + b = [(x_c - 0.5 * w), (y_c - 0.5 * h), + (x_c + 0.5 * w), (y_c + 0.5 * h)] + return torch.stack(b, dim=1) + +def rescale_bboxes(out_bbox, size): + img_w, img_h = size + b = box_cxcywh_to_xyxy(out_bbox) + b = b * torch.tensor([img_w, img_h, img_w, img_h], dtype=torch.float32) + return b + + +def fig2img(fig): + buf = io.BytesIO() + fig.savefig(buf) + buf.seek(0) + img = Image.open(buf) + return img + + +def plot_results(pil_img, prob, boxes): + plt.figure(figsize=(16,10)) + plt.imshow(pil_img) + ax = plt.gca() + colors = COLORS * 100 + for p, (xmin, ymin, xmax, ymax), c in zip(prob, boxes.tolist(), colors): + ax.add_patch(plt.Rectangle((xmin, ymin), xmax - xmin, ymax - ymin, + fill=False, color=c, linewidth=3)) + cl = p.argmax() + text = f'{CLASSES[cl]}: {p[cl]:0.2f}' + ax.text(xmin, ymin, text, fontsize=15, + bbox=dict(facecolor='yellow', alpha=0.5)) + plt.axis('off') + + return fig2img(plt.gcf()) + + +feature_extractor = DetrFeatureExtractor.from_pretrained('facebook/detr-resnet-101-dc5') +model = DetrForObjectDetection.from_pretrained('facebook/detr-resnet-101-dc5') + + +def detect_object(image): + inputs = feature_extractor(images=image, return_tensors="pt") + outputs = model(**inputs) + + probas = outputs.logits.softmax(-1)[0, :, :-1] + keep = probas.max(-1).values > 0.9 + + # convert boxes from [0; 1] to image scales + bboxes_scaled = rescale_bboxes(outputs.pred_boxes[0, keep], image.size) + + return plot_results(image, probas[keep], bboxes_scaled) + + +with gr.Blocks(theme=theme, css="footer {visibility: hidden}") as demo: + gr.Markdown(""" +
็›ฎๆ ‡ๆฃ€ๆต‹
+ """) + with gr.Row(): + with gr.Column(): + box1 = gr.Image(label="ๅ›พ็‰‡", type="pil") + with gr.Row(): + button = gr.Button("ๆไบค", variant="primary") + box2 = gr.Image(label="ๅ›พ็‰‡") + + button.click(fn=detect_object, inputs=box1, outputs=box2) + examples = gr.Examples(examples=[['cat.jpg']], inputs=[box1], label="ไพ‹ๅญ") + + +if __name__ == "__main__": + demo.queue(concurrency_count=3).launch(server_name = "0.0.0.0") diff --git a/cat.jpg b/cat.jpg new file mode 100644 index 0000000..e131e8e Binary files /dev/null and b/cat.jpg differ diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..fcaa654 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,9 @@ +gradio +huggingface_hub +torch +transformers +timm +matplotlib +Pillow +requests +