# Polygon Measurement Tool
A Python package for measuring polygons in YOLO format annotation files with UI features and reference scale measurement.
## Features
- **Enhanced UI**: Crosshair cursor overlay for precise measurement
- **High Accuracy**: Three-measurement reference scale averaging
- **Real-time Preview**: Live measurement display with visual feedback
- **Cross-platform**: Works on Windows, macOS, and Linux
- **GUI Integration**: Directory selection dialog for ease of use
- **Batch Processing**: Process multiple image-label pairs automatically
## Installation
### From PyPI (recommended)
```bash
pip install polygon-measure
```
### From Source
```bash
git clone https://github.com/
cd polygon-measure
pip install -e .
```
### Development Installation
```bash
pip install -e ".[dev]"
```
## Requirements
- Python 3.7+
- OpenCV 4.5.0+
- NumPy 1.19.0+
- Pandas 1.1.0+
- SciPy 1.5.0+
## Usage
### Command Line Interface
#### Using GUI (recommended)
```bash
polygon-measure --gui
```
#### Using Command Line Arguments
```bash
polygon-measure --images ./images --labels ./labels --output ./measurements
```
#### Using Short Arguments
```bash
polygon-measure -i ./images -l ./labels -o ./measurements
```
### Python API
```python
from polygon_measure import EnhancedPolygonMeasurementTool
# Initialize the tool
tool = EnhancedPolygonMeasurementTool(
images_dir="./images",
labels_dir="./labels",
output_dir="./measurements"
)
# Run the measurement process
tool.run()
```
### Run as Module
```bash
python -m polygon_measure --gui
```
## How It Works
### 1. Scale Setting Process
For each image, you need to set the reference scale:
1. **Draw 3 reference lines** on the ruler (each representing 1 cm)
2. **Press 'S'** after drawing each line to save it
3. **Tool calculates average** scale from the 3 measurements
4. **Statistical validation** ensures measurement consistency
### 2. Measurement Process
- Load YOLO format label files automatically
- Calculate polygon dimensions using the reference scale
- Export measurements to CSV format
- Process multiple image-label pairs in batch
### 3. Controls
During scale setting:
- **S** - Save current measurement
- **R** - Reset/redraw current line
- **G** - Toggle grid overlay
- **Q** - Quit/skip current image
- **ESC** - Exit tool
## Algorithm & Mathematical Implementation
### Measurement Algorithm Flowchart
```mermaid
flowchart TD
A["Input: Polygon Points<br/>(normalized coordinates)<br/>+ Image Shape"] --> B{"Polygon has<br/>≥ 3 points?"}
B -->|No| C["Return: max_length=0<br/>max_width=0<br/>area=0"]
B -->|Yes| D["Convert Normalized to<br/>Pixel Coordinates<br/><br/>x_pixel = x_norm × width<br/>y_pixel = y_norm × height"]
D --> E["Calculate Max Length<br/>(Max Distance Between Any Two Points)"]
E --> F["Calculate Max Width<br/>(Perpendicular to Longest Dimension)"]
F --> G{"SciPy Available<br/>& Convex Hull<br/>Succeeds?"}
G -->|Yes| H["Advanced Method:<br/>1. Generate Convex Hull<br/>2. For each edge:<br/> - Find perpendicular vector<br/> - Project all points<br/> - Calculate width<br/>3. Return maximum width"]
G -->|No| I["Simple Fallback Method:<br/>Bounding Box Approach<br/><br/>width_x = max_x - min_x<br/>width_y = max_y - min_y<br/>return min(width_x, width_y)"]
H --> J["Calculate Area<br/>(Shoelace Formula)"]
I --> J
J --> K["Return Dictionary:<br/>{'max_length': float,<br/> 'max_width': float,<br/> 'area': float}"]
style A fill:#e1f5fe
style C fill:#ffebee
style K fill:#e8f5e8
style G fill:#fff3e0
```
### Mathematical Formulas
#### 1. Coordinate Conversion
Convert from normalized YOLO coordinates (0-1 range) to pixel coordinates:
```
x_pixel = x_normalized × image_width
y_pixel = y_normalized × image_height
```
#### 2. Maximum Length Calculation
The maximum length is computed as the greatest Euclidean distance between any two vertices of the polygon.
**Euclidean Distance Formula:**
```
distance = √[(x₂ - x₁)² + (y₂ - y₁)²]
```
**Maximum Length:**
```
max_length = max{distance(pᵢ, pⱼ) | i,j ∈ {1,2,...,n}, i ≠ j}
```
where p₁, p₂, ..., pₙ are the polygon vertices.
#### 3. Maximum Width Calculation
##### Advanced Method (Convex Hull Approach)
For accurate width measurement, the algorithm uses the convex hull and calculates the width perpendicular to each edge:
1. **Edge Vector:** `e⃗ = p₂ - p₁`
2. **Unit Edge Vector:** `û = e⃗ / ||e⃗||`
3. **Perpendicular Unit Vector:** `n̂ = [-û_y, û_x]`
4. **Width for each edge:**
```
width = max{n̂ · pᵢ} - min{n̂ · pᵢ}
```
where the dot product `n̂ · pᵢ` projects point pᵢ onto the perpendicular direction.
5. **Maximum Width:** `max_width = max{width_edge₁, width_edge₂, ..., width_edgeₖ}`
##### Simple Fallback Method
When SciPy is unavailable or convex hull computation fails:
```
width_x = max(x_coordinates) - min(x_coordinates)
width_y = max(y_coordinates) - min(y_coordinates)
max_width = min(width_x, width_y)
```
#### 4. Area Calculation (Shoelace Formula)
The polygon area is calculated using the Shoelace formula¹:
For a polygon with vertices (x₁,y₁), (x₂,y₂), ..., (xₙ,yₙ):
```
Area = ½|∑ᵢ₌₁ⁿ (xᵢy_{i+1} - x_{i+1}yᵢ)|
```
where indices are taken modulo n (i.e., x_{n+1} = x₁, y_{n+1} = y₁).
### Implementation Features
- **Robust Fallback**: Automatically switches to simpler algorithms when advanced libraries are unavailable
- **Pixel-Perfect Accuracy**: All calculations performed in pixel space for maximum precision
- **Convex Hull Optimization**: Uses computational geometry for true maximum width measurement
- **Statistical Validation**: Reference scale measurements include coefficient of variation analysis
### References
1. Shoelace Formula (Surveyor's Formula): Braden, Bart (1986). "The Surveyor's Area Formula". *The College Mathematics Journal*. 17 (4): 326–337.
2. Convex Hull Algorithms: de Berg, Mark; van Kreveld, Marc; Overmars, Mark; Schwarzkopf, Otfried (2000). *Computational Geometry: Algorithms and Applications*. Springer-Verlag.
3. Euclidean Distance: Derived from the Pythagorean theorem, fundamental to metric geometry.
## Output Format
The tool generates CSV files with the following columns:
- `image_name` - Name of the processed image
- `polygon_count` - Total number of polygons in the image
- `polygon_id` - ID of the current polygon
- `max_length_cm` - Maximum length in centimeters
- `max_length_pixels` - Maximum length in pixels
- `max_width_cm` - Maximum width in centimeters
- `max_width_pixels` - Maximum width in pixels
- `area_cm2` - Area in square centimeters
- `area_pixels2` - Area in square pixels
- `scale_pixels_per_cm` - Scale factor used for conversion
## Directory Structure
```
your-project/
├── images/ # Input images
├── labels/ # YOLO format label files (.txt)
└── measurements/ # Output CSV files
```
## YOLO Label Format
The tool expects YOLO segmentation format:
```
class_id x1 y1 x2 y2 x3 y3 ... xn yn
```
Where coordinates are normalized (0-1) relative to image dimensions.
## Advanced Features
### Statistical Analysis
- Measures consistency across the 3 reference measurements
- Warns if coefficient of variation exceeds 10%
- Provides standard deviation and mean calculations
### Visual Enhancements
- Large, readable fonts with high contrast
- Smart text positioning to avoid UI overlap
- Grid overlay for precise alignment
- Color-coded measurement panels
### Error Handling
- Graceful fallback for missing scipy (uses simple width calculation)
- Validation of input directories and files
- Comprehensive error messages and logging
## Troubleshooting
### Common Issues
1. **No matching files found**
- Ensure image and label files have matching names
- Check that label files have `.txt` extension
- Verify directory paths are correct
2. **Scale setting issues**
- Ensure you complete all 3 reference measurements
- Press 'S' after drawing each line
- Check that reference lines are drawn on a ruler
3. **GUI not working**
- Install tkinter: `sudo apt-get install python3-tk` (Linux)
- Use command line arguments as fallback
## Development
### Project Structure
```
polygon_measure/
├── __init__.py
├── __main__.py
├── cli.py
├── config.py
├── core/
│ ├── __init__.py
│ ├── measurement.py
│ └── geometry.py
├── ui/
│ ├── __init__.py
│ ├── directory_selector.py
│ └── display.py
└── utils/
├── __init__.py
└── file_utils.py
```
## Contributing
1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Add tests if applicable
5. Submit a pull request
## Support
For issues and questions:
- Review the command line help: `polygon-measure --help`
- Create an issue on GitHub
Raw data
{
"_id": null,
"home_page": "https://github.com/Vicellken/polygon-measure",
"name": "polygon-measure",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.9",
"maintainer_email": null,
"keywords": "yolo, polygon, measurement, computer-vision, annotation, segmentation",
"author": "yifeigu",
"author_email": null,
"download_url": "https://files.pythonhosted.org/packages/ec/29/1f4b74e34d29b9fef3379b130e5cb9271eaa351cbbf77f03d56a1954a5fe/polygon_measure-2.0.2.tar.gz",
"platform": null,
"description": "# Polygon Measurement Tool\n\nA Python package for measuring polygons in YOLO format annotation files with UI features and reference scale measurement.\n\n## Features\n\n- **Enhanced UI**: Crosshair cursor overlay for precise measurement\n- **High Accuracy**: Three-measurement reference scale averaging\n- **Real-time Preview**: Live measurement display with visual feedback\n- **Cross-platform**: Works on Windows, macOS, and Linux\n- **GUI Integration**: Directory selection dialog for ease of use\n- **Batch Processing**: Process multiple image-label pairs automatically\n\n## Installation\n\n### From PyPI (recommended)\n\n```bash\npip install polygon-measure\n```\n\n### From Source\n\n```bash\ngit clone https://github.com/\ncd polygon-measure\npip install -e .\n```\n\n### Development Installation\n\n```bash\npip install -e \".[dev]\"\n```\n\n## Requirements\n\n- Python 3.7+\n- OpenCV 4.5.0+\n- NumPy 1.19.0+\n- Pandas 1.1.0+\n- SciPy 1.5.0+\n\n## Usage\n\n### Command Line Interface\n\n#### Using GUI (recommended)\n\n```bash\npolygon-measure --gui\n```\n\n#### Using Command Line Arguments\n\n```bash\npolygon-measure --images ./images --labels ./labels --output ./measurements\n```\n\n#### Using Short Arguments\n\n```bash\npolygon-measure -i ./images -l ./labels -o ./measurements\n```\n\n### Python API\n\n```python\nfrom polygon_measure import EnhancedPolygonMeasurementTool\n\n# Initialize the tool\ntool = EnhancedPolygonMeasurementTool(\n images_dir=\"./images\",\n labels_dir=\"./labels\",\n output_dir=\"./measurements\"\n)\n\n# Run the measurement process\ntool.run()\n```\n\n### Run as Module\n\n```bash\npython -m polygon_measure --gui\n```\n\n## How It Works\n\n### 1. Scale Setting Process\n\nFor each image, you need to set the reference scale:\n\n1. **Draw 3 reference lines** on the ruler (each representing 1 cm)\n2. **Press 'S'** after drawing each line to save it\n3. **Tool calculates average** scale from the 3 measurements\n4. **Statistical validation** ensures measurement consistency\n\n### 2. Measurement Process\n\n- Load YOLO format label files automatically\n- Calculate polygon dimensions using the reference scale\n- Export measurements to CSV format\n- Process multiple image-label pairs in batch\n\n### 3. Controls\n\nDuring scale setting:\n\n- **S** - Save current measurement\n- **R** - Reset/redraw current line\n- **G** - Toggle grid overlay\n- **Q** - Quit/skip current image\n- **ESC** - Exit tool\n\n## Algorithm & Mathematical Implementation\n\n### Measurement Algorithm Flowchart\n\n```mermaid\nflowchart TD\n A[\"Input: Polygon Points<br/>(normalized coordinates)<br/>+ Image Shape\"] --> B{\"Polygon has<br/>\u2265 3 points?\"}\n \n B -->|No| C[\"Return: max_length=0<br/>max_width=0<br/>area=0\"]\n \n B -->|Yes| D[\"Convert Normalized to<br/>Pixel Coordinates<br/><br/>x_pixel = x_norm \u00d7 width<br/>y_pixel = y_norm \u00d7 height\"]\n \n D --> E[\"Calculate Max Length<br/>(Max Distance Between Any Two Points)\"]\n \n E --> F[\"Calculate Max Width<br/>(Perpendicular to Longest Dimension)\"]\n \n F --> G{\"SciPy Available<br/>& Convex Hull<br/>Succeeds?\"}\n \n G -->|Yes| H[\"Advanced Method:<br/>1. Generate Convex Hull<br/>2. For each edge:<br/> - Find perpendicular vector<br/> - Project all points<br/> - Calculate width<br/>3. Return maximum width\"]\n \n G -->|No| I[\"Simple Fallback Method:<br/>Bounding Box Approach<br/><br/>width_x = max_x - min_x<br/>width_y = max_y - min_y<br/>return min(width_x, width_y)\"]\n \n H --> J[\"Calculate Area<br/>(Shoelace Formula)\"]\n I --> J\n \n J --> K[\"Return Dictionary:<br/>{'max_length': float,<br/> 'max_width': float,<br/> 'area': float}\"]\n \n style A fill:#e1f5fe\n style C fill:#ffebee\n style K fill:#e8f5e8\n style G fill:#fff3e0\n```\n\n### Mathematical Formulas\n\n#### 1. Coordinate Conversion\nConvert from normalized YOLO coordinates (0-1 range) to pixel coordinates:\n\n```\nx_pixel = x_normalized \u00d7 image_width\ny_pixel = y_normalized \u00d7 image_height\n```\n\n#### 2. Maximum Length Calculation\nThe maximum length is computed as the greatest Euclidean distance between any two vertices of the polygon.\n\n**Euclidean Distance Formula:**\n```\ndistance = \u221a[(x\u2082 - x\u2081)\u00b2 + (y\u2082 - y\u2081)\u00b2]\n```\n\n**Maximum Length:**\n```\nmax_length = max{distance(p\u1d62, p\u2c7c) | i,j \u2208 {1,2,...,n}, i \u2260 j}\n```\nwhere p\u2081, p\u2082, ..., p\u2099 are the polygon vertices.\n\n#### 3. Maximum Width Calculation\n\n##### Advanced Method (Convex Hull Approach)\nFor accurate width measurement, the algorithm uses the convex hull and calculates the width perpendicular to each edge:\n\n1. **Edge Vector:** `e\u20d7 = p\u2082 - p\u2081`\n2. **Unit Edge Vector:** `\u00fb = e\u20d7 / ||e\u20d7||`\n3. **Perpendicular Unit Vector:** `n\u0302 = [-\u00fb_y, \u00fb_x]`\n4. **Width for each edge:**\n ```\n width = max{n\u0302 \u00b7 p\u1d62} - min{n\u0302 \u00b7 p\u1d62}\n ```\n where the dot product `n\u0302 \u00b7 p\u1d62` projects point p\u1d62 onto the perpendicular direction.\n\n5. **Maximum Width:** `max_width = max{width_edge\u2081, width_edge\u2082, ..., width_edge\u2096}`\n\n##### Simple Fallback Method\nWhen SciPy is unavailable or convex hull computation fails:\n```\nwidth_x = max(x_coordinates) - min(x_coordinates)\nwidth_y = max(y_coordinates) - min(y_coordinates)\nmax_width = min(width_x, width_y)\n```\n\n#### 4. Area Calculation (Shoelace Formula)\nThe polygon area is calculated using the Shoelace formula\u00b9:\n\nFor a polygon with vertices (x\u2081,y\u2081), (x\u2082,y\u2082), ..., (x\u2099,y\u2099):\n\n```\nArea = \u00bd|\u2211\u1d62\u208c\u2081\u207f (x\u1d62y_{i+1} - x_{i+1}y\u1d62)|\n```\n\nwhere indices are taken modulo n (i.e., x_{n+1} = x\u2081, y_{n+1} = y\u2081).\n\n### Implementation Features\n\n- **Robust Fallback**: Automatically switches to simpler algorithms when advanced libraries are unavailable\n- **Pixel-Perfect Accuracy**: All calculations performed in pixel space for maximum precision\n- **Convex Hull Optimization**: Uses computational geometry for true maximum width measurement\n- **Statistical Validation**: Reference scale measurements include coefficient of variation analysis\n\n### References\n\n1. Shoelace Formula (Surveyor's Formula): Braden, Bart (1986). \"The Surveyor's Area Formula\". *The College Mathematics Journal*. 17 (4): 326\u2013337.\n2. Convex Hull Algorithms: de Berg, Mark; van Kreveld, Marc; Overmars, Mark; Schwarzkopf, Otfried (2000). *Computational Geometry: Algorithms and Applications*. Springer-Verlag.\n3. Euclidean Distance: Derived from the Pythagorean theorem, fundamental to metric geometry.\n\n## Output Format\n\nThe tool generates CSV files with the following columns:\n\n- `image_name` - Name of the processed image\n- `polygon_count` - Total number of polygons in the image\n- `polygon_id` - ID of the current polygon\n- `max_length_cm` - Maximum length in centimeters\n- `max_length_pixels` - Maximum length in pixels\n- `max_width_cm` - Maximum width in centimeters\n- `max_width_pixels` - Maximum width in pixels\n- `area_cm2` - Area in square centimeters\n- `area_pixels2` - Area in square pixels\n- `scale_pixels_per_cm` - Scale factor used for conversion\n\n## Directory Structure\n\n```\nyour-project/\n\u251c\u2500\u2500 images/ # Input images\n\u251c\u2500\u2500 labels/ # YOLO format label files (.txt)\n\u2514\u2500\u2500 measurements/ # Output CSV files\n```\n\n## YOLO Label Format\n\nThe tool expects YOLO segmentation format:\n\n```\nclass_id x1 y1 x2 y2 x3 y3 ... xn yn\n```\n\nWhere coordinates are normalized (0-1) relative to image dimensions.\n\n## Advanced Features\n\n### Statistical Analysis\n\n- Measures consistency across the 3 reference measurements\n- Warns if coefficient of variation exceeds 10%\n- Provides standard deviation and mean calculations\n\n### Visual Enhancements\n\n- Large, readable fonts with high contrast\n- Smart text positioning to avoid UI overlap\n- Grid overlay for precise alignment\n- Color-coded measurement panels\n\n### Error Handling\n\n- Graceful fallback for missing scipy (uses simple width calculation)\n- Validation of input directories and files\n- Comprehensive error messages and logging\n\n## Troubleshooting\n\n### Common Issues\n\n1. **No matching files found**\n\n - Ensure image and label files have matching names\n - Check that label files have `.txt` extension\n - Verify directory paths are correct\n\n2. **Scale setting issues**\n\n - Ensure you complete all 3 reference measurements\n - Press 'S' after drawing each line\n - Check that reference lines are drawn on a ruler\n\n3. **GUI not working**\n - Install tkinter: `sudo apt-get install python3-tk` (Linux)\n - Use command line arguments as fallback\n\n## Development\n\n### Project Structure\n\n```\npolygon_measure/\n\u251c\u2500\u2500 __init__.py\n\u251c\u2500\u2500 __main__.py\n\u251c\u2500\u2500 cli.py\n\u251c\u2500\u2500 config.py\n\u251c\u2500\u2500 core/\n\u2502 \u251c\u2500\u2500 __init__.py\n\u2502 \u251c\u2500\u2500 measurement.py\n\u2502 \u2514\u2500\u2500 geometry.py\n\u251c\u2500\u2500 ui/\n\u2502 \u251c\u2500\u2500 __init__.py\n\u2502 \u251c\u2500\u2500 directory_selector.py\n\u2502 \u2514\u2500\u2500 display.py\n\u2514\u2500\u2500 utils/\n \u251c\u2500\u2500 __init__.py\n \u2514\u2500\u2500 file_utils.py\n```\n\n## Contributing\n\n1. Fork the repository\n2. Create a feature branch\n3. Make your changes\n4. Add tests if applicable\n5. Submit a pull request\n\n## Support\n\nFor issues and questions:\n\n- Review the command line help: `polygon-measure --help`\n- Create an issue on GitHub\n",
"bugtrack_url": null,
"license": null,
"summary": "Polygon measurement tool for YOLO segmentation datasets",
"version": "2.0.2",
"project_urls": {
"Bug Reports": "https://github.com/Vicellken/polygon-measure/issues",
"Homepage": "https://github.com/Vicellken/polygon-measure",
"Source": "https://github.com/Vicellken/polygon-measure"
},
"split_keywords": [
"yolo",
" polygon",
" measurement",
" computer-vision",
" annotation",
" segmentation"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "b8b6fd9238b9d84f0411ff29215b02fc6b35e82ec66782a32dff251440143969",
"md5": "eef3066414415e67f414bb40d4797a79",
"sha256": "62e85822f0f8db9477c36e00ccb4b79e68ae5e2ee362cd19e5e7e772833bba85"
},
"downloads": -1,
"filename": "polygon_measure-2.0.2-py3-none-any.whl",
"has_sig": false,
"md5_digest": "eef3066414415e67f414bb40d4797a79",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.9",
"size": 27297,
"upload_time": "2025-07-25T02:53:45",
"upload_time_iso_8601": "2025-07-25T02:53:45.144956Z",
"url": "https://files.pythonhosted.org/packages/b8/b6/fd9238b9d84f0411ff29215b02fc6b35e82ec66782a32dff251440143969/polygon_measure-2.0.2-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "ec291f4b74e34d29b9fef3379b130e5cb9271eaa351cbbf77f03d56a1954a5fe",
"md5": "af6ddf11a79fd295514663ff8346bd82",
"sha256": "8b89e9d694af1194a09466d1e585b13e25cb5a62891c3c2465ad50e0dc6c48b9"
},
"downloads": -1,
"filename": "polygon_measure-2.0.2.tar.gz",
"has_sig": false,
"md5_digest": "af6ddf11a79fd295514663ff8346bd82",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.9",
"size": 28084,
"upload_time": "2025-07-25T02:53:46",
"upload_time_iso_8601": "2025-07-25T02:53:46.563876Z",
"url": "https://files.pythonhosted.org/packages/ec/29/1f4b74e34d29b9fef3379b130e5cb9271eaa351cbbf77f03d56a1954a5fe/polygon_measure-2.0.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-07-25 02:53:46",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "Vicellken",
"github_project": "polygon-measure",
"github_not_found": true,
"lcname": "polygon-measure"
}