AI for Agriculture Crop Image Analysis

We design and deploy artificial intelligence systems: from prototype to production-ready solutions. Our team combines expertise in machine learning, data engineering and MLOps to make AI work not in the lab, but in real business.
Showing 1 of 1 servicesAll 1566 services
AI for Agriculture Crop Image Analysis
Complex
~1-2 weeks
FAQ
AI Development Areas
AI Solution Development Stages
Latest works
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1161
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1041
  • image_logo-advance_0.png
    B2B Advance company logo design
    561
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    823
  • image_logo-aider_0.jpg
    AIDER company logo development
    762
  • image_crm_chasseurs_493_0.webp
    CRM development for Chasseurs
    848

Разработка AI для сельского хозяйства (анализ снимков посевов)

Precision agriculture — точное земледелие с использованием данных: спутниковые снимки, аэрофотосъёмка с дронов, наземные датчики. CV-компонент: анализ состояния посевов по изображениям для выявления стресса, болезней, вредителей, оценки урожайности. Результат — зональные карты полей для дифференцированного применения удобрений и средств защиты.

Индексы вегетации из мультиспектральных снимков

Мультиспектральные камеры на дронах захватывают NIR (near-infrared) диапазон, недоступный RGB-камерам. NDVI (Normalized Difference Vegetation Index) — стандартный показатель здоровья растений:

import numpy as np
import rasterio
import matplotlib.pyplot as plt
import matplotlib.colors as colors

class CropHealthAnalyzer:
    def calculate_ndvi(self, red_band: np.ndarray,
                        nir_band: np.ndarray) -> np.ndarray:
        """NDVI = (NIR - Red) / (NIR + Red)"""
        red = red_band.astype(np.float32)
        nir = nir_band.astype(np.float32)
        ndvi = np.where(
            (nir + red) > 0,
            (nir - red) / (nir + red),
            0
        )
        return np.clip(ndvi, -1, 1)

    def calculate_ndre(self, red_edge: np.ndarray,
                        nir: np.ndarray) -> np.ndarray:
        """NDRE — чувствительнее NDVI для раннего стресса"""
        return (nir - red_edge) / (nir + red_edge + 1e-8)

    def calculate_indices_batch(self, multispectral_path: str) -> dict:
        """Расчёт всех индексов из мультиспектрального GeoTIFF"""
        with rasterio.open(multispectral_path) as src:
            # Предполагаем порядок: Blue, Green, Red, RedEdge, NIR
            blue = src.read(1).astype(np.float32)
            green = src.read(2).astype(np.float32)
            red = src.read(3).astype(np.float32)
            red_edge = src.read(4).astype(np.float32)
            nir = src.read(5).astype(np.float32)
            transform = src.transform
            crs = src.crs

        indices = {
            'ndvi': self.calculate_ndvi(red, nir),
            'ndre': self.calculate_ndre(red_edge, nir),
            'gndvi': (nir - green) / (nir + green + 1e-8),  # Green NDVI
            'evi': 2.5 * (nir - red) / (nir + 6*red - 7.5*blue + 1 + 1e-8),
        }

        return indices, transform, crs

    def classify_crop_health(self, ndvi: np.ndarray) -> np.ndarray:
        """Классификация здоровья посевов по NDVI"""
        health_map = np.zeros_like(ndvi, dtype=np.uint8)
        health_map[ndvi < 0.1] = 0   # Почва/нет растительности
        health_map[(ndvi >= 0.1) & (ndvi < 0.3)] = 1   # Стресс/разреженный
        health_map[(ndvi >= 0.3) & (ndvi < 0.5)] = 2   # Умеренный
        health_map[(ndvi >= 0.5) & (ndvi < 0.7)] = 3   # Хорошее
        health_map[ndvi >= 0.7] = 4   # Отличное
        return health_map

Детекция болезней и вредителей по RGB-снимкам

from ultralytics import YOLO
import cv2

class CropDiseaseDetector:
    def __init__(self, model_path: str):
        # YOLOv8 дообученный на PlantVillage Dataset + кастомные данные
        self.model = YOLO(model_path)
        self.disease_classes = [
            'healthy', 'early_blight', 'late_blight', 'leaf_mold',
            'septoria_leaf_spot', 'spider_mites', 'target_spot',
            'yellow_leaf_curl', 'mosaic_virus', 'bacterial_spot'
        ]

    def analyze_leaf(self, leaf_image: np.ndarray) -> dict:
        results = self.model(leaf_image, conf=0.4)
        detections = []

        for box in results[0].boxes:
            disease = self.disease_classes[int(box.cls)]
            detections.append({
                'disease': disease,
                'confidence': float(box.conf),
                'bbox': box.xyxy[0].tolist(),
                'severity': self._estimate_severity(leaf_image, box)
            })

        # Общий балл здоровья
        if not detections:
            health_score = 1.0
        else:
            max_disease_conf = max(d['confidence'] for d in detections
                                    if d['disease'] != 'healthy')
            health_score = 1.0 - max_disease_conf

        return {
            'health_score': health_score,
            'detections': detections,
            'needs_treatment': health_score < 0.6
        }

Зональные карты для дифференцированного внесения

import geopandas as gpd
from shapely.geometry import shape
import json

def create_prescription_map(ndvi_array: np.ndarray,
                              transform,
                              field_boundary: gpd.GeoDataFrame) -> dict:
    """
    Создание карты рекомендаций по зонам (prescription map)
    для переменной нормы внесения удобрений
    """
    health_zones = classify_into_zones(ndvi_array, n_zones=4)

    # Векторизация растровых зон
    from rasterio.features import shapes
    zone_geometries = list(shapes(health_zones.astype('uint8'), transform=transform))

    prescription = []
    for geom, zone_value in zone_geometries:
        # Норма внесения N по зонам (кг/га)
        n_rate = {1: 120, 2: 90, 3: 60, 4: 30}[int(zone_value)] if zone_value > 0 else 0
        prescription.append({
            'geometry': geom,
            'zone': int(zone_value),
            'n_rate_kg_ha': n_rate,
            'action': 'apply_fertilizer' if n_rate > 0 else 'skip'
        })

    return prescription

Integration с агротехническим ПО

  • John Deere Operations Center: импорт prescription maps в формате shapefile/geojson
  • ISOBUS: стандарт передачи задания на технику
  • FMIS (Farm Management Information System): хранение полевых данных
Применение Данные Точность
NDVI мониторинг Мультиспектральный дрон Корреляция с урожайностью 0.82
Детекция болезней листьев RGB фото 87–93% accuracy
Оценка урожайности RGB + NIR MAE 8–15% от реальной
Масштаб Срок
Пилот: 1 культура, 1 поле 4–6 недель
Хозяйство: 5–10 культур 8–14 недель
Региональная платформа 16–24 недели