You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

冰壶投掷后壶体中心坐标提取技术需求(R/Python)

Alright, let's figure out how to get those accurate curling stone coordinates saved to CSV. Since you're having trouble with R, I'll cover both a refined R approach to fix your current setup and a straightforward Python solution that’s perfect for this computer vision task.

Refined R Solution Using magick and opencv

Your poor detection results are almost certainly from relying on naive RGB color picking or not filtering out tiny noise objects. Switching to the HSV color space (way more stable for color detection) and adding contour filtering will fix this.

Step 1: Install Required Packages

First, make sure you have these tools installed:

install.packages(c("magick", "opencv", "dplyr"))

Step 2: Full Implementation Code

library(magick)
library(opencv)
library(dplyr)

# Load your curling frame image
img <- image_read("curling_frame.jpg")
# Convert image to a matrix compatible with OpenCV
img_mat <- image_data(img, "rgba") %>% as.integer() %>% drop() %>% aperm(c(2,3,1))

# Switch to HSV color space (better for consistent color detection)
hsv_img <- cv_cvtColor(img_mat, COLOR_BGR2HSV)

# Define HSV ranges for red (note red has two separate ranges) and yellow
lower_red1 <- c(0, 120, 70)
upper_red1 <- c(10, 255, 255)
lower_red2 <- c(170, 120, 70)
upper_red2 <- c(180, 255, 255)
lower_yellow <- c(20, 100, 100)
upper_yellow <- c(30, 255, 255)

# Create color masks and combine them
mask_red1 <- cv_inRange(hsv_img, lower_red1, upper_red1)
mask_red2 <- cv_inRange(hsv_img, lower_red2, upper_red2)
mask_red <- cv_bitwise_or(mask_red1, mask_red2)
mask_yellow <- cv_inRange(hsv_img, lower_yellow, upper_yellow)
mask_combined <- cv_bitwise_or(mask_red, mask_yellow)

# Clean up the mask to remove small noise (tiny dots/circles)
kernel <- cv_getStructuringElement(MORPH_ELLIPSE, c(5,5))
mask_clean <- cv_morphologyEx(mask_combined, MORPH_OPEN, kernel)
mask_clean <- cv_morphologyEx(mask_clean, MORPH_CLOSE, kernel)

# Detect contours and filter out small objects (exclude top/bottom tiny circles)
contours <- cv_findContours(mask_clean, mode = RETR_EXTERNAL, method = CHAIN_APPROX_SIMPLE)
# Adjust min_area based on your image resolution (small circles will be way smaller than stones)
min_area <- 500
valid_contours <- Filter(function(c) cv_contourArea(c) > min_area, contours)

# Calculate center coordinates for each valid stone
stone_centers <- lapply(valid_contours, function(c) {
  moments <- cv_moments(c)
  x <- moments$m10 / moments$m00
  y <- moments$m01 / moments$m00
  data.frame(x = round(x, 2), y = round(y, 2))
}) %>% bind_rows()

# Save results to CSV
write.csv(stone_centers, "curling_stone_coordinates.csv", row.names = FALSE)

Python Solution with OpenCV & Pandas

If you’re open to switching, Python’s OpenCV ecosystem is super mature for this kind of task. This implementation is robust and easy to tweak.

Step 1: Install Dependencies

pip install opencv-python pandas numpy

Step 2: Full Implementation Code

import cv2
import numpy as np
import pandas as pd

# Load your curling frame image
img = cv2.imread("curling_frame.jpg")
# Convert to HSV color space
hsv_img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

# Define HSV ranges for red and yellow
lower_red1 = np.array([0, 120, 70])
upper_red1 = np.array([10, 255, 255])
lower_red2 = np.array([170, 120, 70])
upper_red2 = np.array([180, 255, 255])
lower_yellow = np.array([20, 100, 100])
upper_yellow = np.array([30, 255, 255])

# Create and combine color masks
mask_red1 = cv2.inRange(hsv_img, lower_red1, upper_red1)
mask_red2 = cv2.inRange(hsv_img, lower_red2, upper_red2)
mask_red = cv2.bitwise_or(mask_red1, mask_red2)
mask_yellow = cv2.inRange(hsv_img, lower_yellow, upper_yellow)
mask_combined = cv2.bitwise_or(mask_red, mask_yellow)

# Clean mask to eliminate small noise
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))
mask_clean = cv2.morphologyEx(mask_combined, cv2.MORPH_OPEN, kernel)
mask_clean = cv2.morphologyEx(mask_clean, cv2.MORPH_CLOSE, kernel)

# Detect contours and filter out tiny objects
contours, _ = cv2.findContours(mask_clean, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
min_area = 500  # Adjust this based on your image's scale
valid_contours = [cnt for cnt in contours if cv2.contourArea(cnt) > min_area]

# Calculate center coordinates for each stone
stone_centers = []
for cnt in valid_contours:
    M = cv2.moments(cnt)
    if M["m00"] != 0:  # Avoid division by zero (edge case)
        cx = int(M["m10"] / M["m00"])
        cy = int(M["m01"] / M["m00"])
        stone_centers.append({"x": cx, "y": cy})

# Save to CSV
df = pd.DataFrame(stone_centers)
df.to_csv("curling_stone_coordinates.csv", index=False)

Quick Tips for Fine-Tuning

  • Adjust min_area: This is the most important parameter. Check the pixel area of the tiny top/bottom circles vs actual stones in your images, then set min_area to a value between the two.
  • Tweak HSV Ranges: If color detection is off, use an HSV color picker tool to get exact ranges for your specific footage (lighting can change how colors appear).
  • Coordinate System Note: In both R and OpenCV, the origin (0,0) is the top-left corner, so y-values increase as you go down the image.

内容的提问来源于stack exchange,提问作者sydg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:37:42