commit 4b2fbfa1af9548801843ba1faad518c32333d333 Author: loveuer Date: Wed Jun 5 16:37:12 2024 +0800 feat: 简单的接口 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..022cc76 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +.vscode +.idea +venv +*.jpg +*.jpeg +.DS_Store \ No newline at end of file diff --git a/main.py b/main.py new file mode 100644 index 0000000..569ff11 --- /dev/null +++ b/main.py @@ -0,0 +1,43 @@ +import cv2 +import numpy as np + +def detect_circles(image_path): + # 读取图像 + img = cv2.imread(image_path, cv2.IMREAD_COLOR) + + # 将图像转换为灰度图 + gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) + + # 使用高斯模糊处理图像 + blurred = cv2.GaussianBlur(gray, (9, 9), 2) + + # 使用霍夫圆检测法检测圆圈 + circles = cv2.HoughCircles(blurred, cv2.HOUGH_GRADIENT, dp=1.2, minDist=30, + param1=80, param2=38, minRadius=15, maxRadius=60) + + # 确认至少检测到一个圆圈 + if circles is not None: + circles = np.round(circles[0, :]).astype("int") + + print(f"检测到 {len(circles)} 个圆圈") + for i, (x, y, r) in enumerate(circles, start=1): # 从1开始计数 + # 在图像中绘制圆圈 + cv2.circle(img, (x, y), r, (0, 255, 0), 4) + # 在图像中绘制圆心 + cv2.circle(img, (x, y), 2, (0, 128, 255), 3) + # 在图像中绘制圆圈编号 + cv2.putText(img, f'{i}', (x - 10, y + 10), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 255), 2) + + # 显示结果图像并处理退出事件 + while True: + cv2.imshow("detected circles", img) + key = cv2.waitKey(1) & 0xFF + if key == 27: # ESC键的ASCII码是27 + break + + cv2.destroyAllWindows() + else: + print("没有检测到圆圈") + +# 调用函数并传递图像路径 +detect_circles("image2.jpg") \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..fd5ba1b --- /dev/null +++ b/requirements.txt @@ -0,0 +1,39 @@ +annotated-types==0.7.0 +anyio==4.4.0 +certifi==2024.6.2 +click==8.1.7 +dnspython==2.6.1 +email_validator==2.1.1 +exceptiongroup==1.2.1 +fastapi==0.111.0 +fastapi-cli==0.0.4 +h11==0.14.0 +httpcore==1.0.5 +httptools==0.6.1 +httpx==0.27.0 +idna==3.7 +Jinja2==3.1.4 +markdown-it-py==3.0.0 +MarkupSafe==2.1.5 +mdurl==0.1.2 +numpy==1.26.4 +opencv-python==4.10.0.82 +orjson==3.10.3 +pillow==10.3.0 +pydantic==2.7.3 +pydantic_core==2.18.4 +Pygments==2.18.0 +python-dotenv==1.0.1 +python-multipart==0.0.9 +PyYAML==6.0.1 +rich==13.7.1 +shellingham==1.5.4 +sniffio==1.3.1 +starlette==0.37.2 +typer==0.12.3 +typing_extensions==4.12.1 +ujson==5.10.0 +uvicorn==0.30.1 +uvloop==0.19.0 +watchfiles==0.22.0 +websockets==12.0 diff --git a/svc.py b/svc.py new file mode 100644 index 0000000..c78ad3e --- /dev/null +++ b/svc.py @@ -0,0 +1,70 @@ +from fastapi import FastAPI, UploadFile, HTTPException +from pydantic import BaseModel +from PIL import Image +import io +import base64 +import cv2 +import numpy as np + +def opencv_image_to_bytes(opencv_image): + """将 OpenCV 图像对象转换为 bytes 对象""" + # 使用 cv2.imencode() 将图像编码为 numpy 数组 + ret, buffer = cv2.imencode('.jpg', opencv_image) + + # 将 numpy 数组转换为 bytes + img_bytes = buffer.tobytes() + + return img_bytes + +def handleImageByCV2(bs: bytes) -> {int, bytes}: + # 读取图像 + img = cv2.imdecode(np.frombuffer(bs, np.uint8), cv2.IMREAD_COLOR) + + # 将图像转换为灰度图 + gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) + + # 使用高斯模糊处理图像 + blurred = cv2.GaussianBlur(gray, (9, 9), 2) + + # 使用霍夫圆检测法检测圆圈 + circles = cv2.HoughCircles(blurred, cv2.HOUGH_GRADIENT, dp=1.2, minDist=30, + param1=80, param2=38, minRadius=15, maxRadius=60) + + # 确认至少检测到一个圆圈 + if circles is not None: + circles = np.round(circles[0, :]).astype("int") + + print(f"检测到 {len(circles)} 个圆圈") + for i, (x, y, r) in enumerate(circles, start=1): # 从1开始计数 + # 在图像中绘制圆圈 + cv2.circle(img, (x, y), r, (0, 255, 0), 4) + # 在图像中绘制圆心 + cv2.circle(img, (x, y), 2, (0, 128, 255), 3) + # 在图像中绘制圆圈编号 + cv2.putText(img, f'{i}', (x - 10, y + 10), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 255), 2) + + return len(circles), opencv_image_to_bytes(img) + else: + return 0, opencv_image_to_bytes(img) + +app = FastAPI() + +class ImageResponse(BaseModel): + image_base64: str + circle_count: int + +@app.post("/upload_image", response_model=ImageResponse) +async def upload_image(image_file: UploadFile): + if not(image_file.filename.endswith('.jpg') or image_file.filename.endswith('.jpeg')): + raise HTTPException(status_code=400, detail="Only jpg or jpeg files are supported") + + image_bytes = await image_file.read() + count, new_bytes = handleImageByCV2(image_bytes) + + img_base64 = base64.b64encode(new_bytes).decode('utf-8') + + return ImageResponse(image_base64=img_base64, circle_count=count) + +if __name__ == '__main__': + import uvicorn + uvicorn.run(app, host="0.0.0.0", port=8000) \ No newline at end of file