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