bloombase/plants/templates/plants/plant_card_extract.html
Stephan Kerkman ba0ca6b169 feat: card scanning, OCR improvements, crop thumbnail, VPC enrichment
- Add scan-to-plant flow: upload card photos, OCR, VPC match on confirm form
- OpenCV CLAHE + adaptive threshold preprocessing; dual psm 6/11 OCR pass
- Regex fixes for OCR misreads: height (s→5), frost (=,„,i,l,G), density, bloom months (E→I)
- Scientific name extraction: passport section + cultivar quote strategy
- Last-wins merge so back card data overrides front card garbage
- Crop thumbnail tool with Cropper.js; cropped image shown in list and detail
- VPC image always supersedes user thumbnail on detail page
- VPC sunlight mapping: zon→full_sun, halfschaduw→part_sun, schaduw→full_shade
- Auto-set thumbnail on plant created from scan

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 21:54:59 +02:00

93 lines
4 KiB
HTML

{% extends "plants/base.html" %}
{% load plant_extras %}
{% block title %}Extract card data — {{ plant.name }} — PlantDB{% endblock %}
{% block content %}
<div class="d-flex align-items-center gap-2 mb-3">
<a href="{% url 'plant_card' plant.pk %}" class="btn btn-sm btn-outline-secondary">← Card</a>
<h5 class="mb-0">Extract from card</h5>
</div>
<p class="text-muted small mb-3">Review the data extracted from your card photos. Correct anything that looks off, then save.</p>
<form method="post" action="{% url 'extract_card_data' plant.pk %}">
{% csrf_token %}
<div class="mb-3">
<label class="form-label fw-semibold">Scientific name</label>
<input type="text" name="scientific_name" class="form-control"
value="{{ extracted.scientific_name|default:'' }}">
</div>
<div class="mb-3">
<label class="form-label fw-semibold">Bloom months</label>
<div class="month-toggle-group">
{% for val, label in month_choices %}
<div class="month-toggle">
<input type="checkbox" id="month_{{ val }}" name="bloom_months" value="{{ val }}"
{% if val in extracted.bloom_months %}checked{% endif %}>
<label for="month_{{ val }}">{{ label|slice:":1" }}</label>
</div>
{% endfor %}
</div>
</div>
<div class="row g-2 mb-3">
<div class="col-6">
<label class="form-label fw-semibold">Height (cm)</label>
<input type="number" name="max_height_cm" class="form-control"
value="{{ extracted.max_height_cm|default:'' }}">
</div>
<div class="col-6">
<label class="form-label fw-semibold">Frost hardiness (°C)</label>
<input type="number" name="frost_hardiness_c" class="form-control"
value="{{ extracted.frost_hardiness_c|default:'' }}">
</div>
</div>
<div class="mb-3">
<label class="form-label fw-semibold">Planting density (per m²)</label>
<input type="number" name="planting_density_m2" class="form-control" style="max-width:140px;"
value="{{ extracted.planting_density_m2|default:'' }}">
</div>
<div class="mb-3">
<label class="form-label fw-semibold">Sunlight <small class="text-muted fw-normal">(select manually — icons can't be read)</small></label>
<div class="d-flex flex-wrap gap-2">
{% for val, label in sunlight_choices %}
<div>
<input type="radio" class="btn-check" name="sunlight"
id="sunlight_{{ val|default:'none' }}" value="{{ val }}"
autocomplete="off"
{% if plant.species.sunlight == val %}checked{% endif %}>
<label class="btn btn-outline-secondary btn-sm" for="sunlight_{{ val|default:'none' }}">{{ label }}</label>
</div>
{% endfor %}
</div>
</div>
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="bee_attractant" name="bee_attractant"
{% if extracted.bee_attractant %}checked{% endif %} disabled>
<label class="form-check-label" for="bee_attractant">🐝 Bee attractant (detected from card)</label>
</div>
{% if plant_photo_preview_url %}
<div class="mb-3">
<img src="{{ plant_photo_preview_url }}" class="rounded mb-2"
style="max-width:100%; max-height:260px; object-fit:contain; display:block;">
<div class="form-check">
<input type="checkbox" class="form-check-input" id="save_plant_photo" name="save_plant_photo" value="1" checked>
<label class="form-check-label" for="save_plant_photo">
📷 Add this photo to gallery
</label>
</div>
</div>
{% endif %}
<div class="d-grid gap-2">
<button type="submit" class="btn btn-success">Save to species</button>
<a href="{% url 'plant_card' plant.pk %}" class="btn btn-outline-secondary">Cancel</a>
</div>
</form>
{% endblock %}