- 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>
93 lines
4 KiB
HTML
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 %}
|