'commit'
This commit is contained in:
@@ -80,8 +80,8 @@ class TeLaiDianCrawler(BaseCrawler):
|
|||||||
if os.path.exists(ad_screen): os.remove(ad_screen)
|
if os.path.exists(ad_screen): os.remove(ad_screen)
|
||||||
|
|
||||||
async def crawl_list_logic(self, d):
|
async def crawl_list_logic(self, d):
|
||||||
# 进入列表页先清理广告
|
# [临时禁用] 广告清理逻辑误触严重,先解决主流程问题
|
||||||
await self.clear_ads(d)
|
# await self.clear_ads(d)
|
||||||
|
|
||||||
# [优化] 向下滚动以刷新/校准地理位置
|
# [优化] 向下滚动以刷新/校准地理位置
|
||||||
# 使用更加显式的 swipe 方式:从屏幕 30% 划到 80%
|
# 使用更加显式的 swipe 方式:从屏幕 30% 划到 80%
|
||||||
|
|||||||
@@ -151,11 +151,11 @@ def detect_price_click_point_cv(image_path):
|
|||||||
|
|
||||||
return [center_x, center_y]
|
return [center_x, center_y]
|
||||||
|
|
||||||
def detect_cards_cv(image_path, top_ratio=0.40, bottom_ratio=0.12):
|
def detect_cards_cv(image_path, top_ratio=0.40, bottom_ratio=0.12):
|
||||||
"""
|
"""
|
||||||
使用计算机图形学 (OpenCV) 检测列表中的场站卡片。
|
使用计算机图形学 (OpenCV) 检测列表中的场站卡片。
|
||||||
"""
|
"""
|
||||||
from Apps.TeLaiDian.Config.Setting import MIN_CARD_HEIGHT
|
from Apps.TeLaiDian.Config.Setting import MIN_CARD_HEIGHT
|
||||||
|
|
||||||
img = read_image(image_path)
|
img = read_image(image_path)
|
||||||
if img is None:
|
if img is None:
|
||||||
@@ -226,14 +226,46 @@ def detect_cards_cv(image_path, top_ratio=0.40, bottom_ratio=0.12):
|
|||||||
min(w, x + cw - padding),
|
min(w, x + cw - padding),
|
||||||
min(bottom_limit, y + ch - padding)
|
min(bottom_limit, y + ch - padding)
|
||||||
])
|
])
|
||||||
|
|
||||||
return cards
|
return cards
|
||||||
|
|
||||||
def draw_rectangles(image_path, bboxes=None, click_points=None):
|
def detect_wide_rounded_card_cv(image_path, min_width_ratio=0.8, min_y_ratio=0.5):
|
||||||
"""
|
img = read_image(image_path)
|
||||||
使用 OpenCV 在图片上绘制矩形框和点击点,生成 _vl.jpg 和 _flag.jpg
|
if img is None:
|
||||||
- _vl.jpg: 仅包含矩形框,供视觉模型参考
|
return []
|
||||||
- _flag.jpg: 包含矩形框和点击点,供人工调试
|
h, w = img.shape[:2]
|
||||||
|
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
|
||||||
|
blur = cv2.GaussianBlur(gray, (7, 7), 0)
|
||||||
|
edges = cv2.Canny(blur, 60, 180)
|
||||||
|
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (15, 15))
|
||||||
|
closed = cv2.morphologyEx(edges, cv2.MORPH_CLOSE, kernel)
|
||||||
|
contours, _ = cv2.findContours(closed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
|
||||||
|
results = []
|
||||||
|
for cnt in contours:
|
||||||
|
x, y, cw, ch = cv2.boundingRect(cnt)
|
||||||
|
center_y = y + ch // 2
|
||||||
|
if cw < int(w * min_width_ratio):
|
||||||
|
continue
|
||||||
|
if center_y < int(h * min_y_ratio):
|
||||||
|
continue
|
||||||
|
rect_area = cw * ch
|
||||||
|
cnt_area = cv2.contourArea(cnt)
|
||||||
|
if rect_area <= 0:
|
||||||
|
continue
|
||||||
|
extent = cnt_area / rect_area
|
||||||
|
approx = cv2.approxPolyDP(cnt, 0.02 * cv2.arcLength(cnt, True), True)
|
||||||
|
if extent < 0.7:
|
||||||
|
continue
|
||||||
|
if len(approx) >= 6 or (len(approx) == 4 and extent > 0.85):
|
||||||
|
results.append([x, y, x + cw, y + ch])
|
||||||
|
results.sort(key=lambda b: b[1])
|
||||||
|
return results
|
||||||
|
|
||||||
|
def draw_rectangles(image_path, bboxes=None, click_points=None):
|
||||||
|
"""
|
||||||
|
使用 OpenCV 在图片上绘制矩形框和点击点,生成 _vl.jpg 和 _flag.jpg
|
||||||
|
- _vl.jpg: 仅包含矩形框,供视觉模型参考
|
||||||
|
- _flag.jpg: 包含矩形框和点击点,供人工调试
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
DEBUG_BOX_COLOR = (0, 255, 0) # 绿色矩形
|
DEBUG_BOX_COLOR = (0, 255, 0) # 绿色矩形
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ if project_root not in sys.path:
|
|||||||
sys.path.append(project_root)
|
sys.path.append(project_root)
|
||||||
|
|
||||||
from Util.VLMKit import VLMKit
|
from Util.VLMKit import VLMKit
|
||||||
from Apps.TeLaiDian.Kit import draw_rectangles, detect_cards_cv, setup_logger, read_image
|
from Apps.TeLaiDian.Kit import draw_rectangles, detect_cards_cv, setup_logger, read_image, detect_wide_rounded_card_cv
|
||||||
from Apps.TeLaiDian.Config.Setting import SAFE_EXCLUDE_RATIO, BOTTOM_SAFE_EXCLUDE_RATIO
|
from Apps.TeLaiDian.Config.Setting import SAFE_EXCLUDE_RATIO, BOTTOM_SAFE_EXCLUDE_RATIO
|
||||||
|
|
||||||
# 初始化日志
|
# 初始化日志
|
||||||
@@ -40,6 +40,17 @@ class ReadImageKit:
|
|||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
|
cv_bboxes = detect_wide_rounded_card_cv(image_path, min_width_ratio=0.8, min_y_ratio=0.5)
|
||||||
|
if cv_bboxes:
|
||||||
|
img = read_image(image_path)
|
||||||
|
if img is not None:
|
||||||
|
h, w = img.shape[:2]
|
||||||
|
bx1, by1, bx2, by2 = cv_bboxes[0]
|
||||||
|
cx = (bx1 + bx2) // 2
|
||||||
|
cy = (by1 + by2) // 2
|
||||||
|
draw_rectangles(image_path, bboxes=[cv_bboxes[0]], click_points=[[cx, cy]])
|
||||||
|
return {"found": True, "reason": "cv", "point": [int(cx * 1000 / w), int(cy * 1000 / h)], "type": "price_card"}
|
||||||
|
|
||||||
res_text = await self.vlm.analyze_image(image_path, prompt)
|
res_text = await self.vlm.analyze_image(image_path, prompt)
|
||||||
json_str = self.vlm.extract_json(res_text)
|
json_str = self.vlm.extract_json(res_text)
|
||||||
data = json.loads(json_str)
|
data = json.loads(json_str)
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user