feat: 简单的接口
This commit is contained in:
		
							
								
								
									
										6
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
.vscode
 | 
			
		||||
.idea
 | 
			
		||||
venv
 | 
			
		||||
*.jpg
 | 
			
		||||
*.jpeg
 | 
			
		||||
.DS_Store
 | 
			
		||||
							
								
								
									
										43
									
								
								main.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								main.py
									
									
									
									
									
										Normal file
									
								
							@@ -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")
 | 
			
		||||
							
								
								
									
										39
									
								
								requirements.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								requirements.txt
									
									
									
									
									
										Normal file
									
								
							@@ -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
 | 
			
		||||
							
								
								
									
										70
									
								
								svc.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								svc.py
									
									
									
									
									
										Normal file
									
								
							@@ -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)
 | 
			
		||||
		Reference in New Issue
	
	Block a user