Оптичне розпізнавання

Припустимо, на нашому WolfRecorder ведеться запис однієї з ваших камер. Нехай, на ній зображено якийсь такий пейзаж.

Як не складно помітити, в поле зору камери потрапляють декілька амперметрів на щитовій. Припустимо, що одні з них, відображають якісь значення, за наявності міської мережі, що виглядає приблизно так:

а інший приходить в дію та щось відображає, після заведення генератора, що на практиці виглядає якось так

Ви ж розумієте, що Ubilling може без проблем, на основі цих даних розпізнавати факт заведення генератора з метою автоматичного моніторингу, одним простеньким скриптиком OnePunch скриптом?

    $wolfRecorderHost='yourwolfrecorderhost.ua'; // хостнейм чи IP вашого WolfRecorder
    $cameraChannel='camerachannelid'; // ідентифікатор каналу вашої камери
    $powerAvailabilityThreshold=90; // рівень яскравості сцени вище якого рахуємо, що генератор завівся
    $debugMode=false; // режим відлагодженя
 
    // описує координати сцени, яка буде аналізуватись
    $controlRegion=array(
        'x1'=>1038,
        'y1'=>455,
        'x2'=>42,
        'y2'=>25
    );
 
    $cameraScreenshotUrl='http://'.$wolfRecorderHost.'/wr/howl/chanshots/'.$cameraChannel.'.jpg';
 
    $watchdogCallbackResult='';
    $generatorState=0;
    $remoteHost=new OmaeUrl($cameraScreenshotUrl);
    $originalImage=$remoteHost->response();
 
    if ($remoteHost->httpCode()==200 and $remoteHost->error()==false) {
        if (!empty($originalImage)) {
        $imageHash=md5($cameraScreenshotUrl.json_encode($controlRegion));
        $originalImagePath='exports/'.$imageHash.'.jpg';
        file_put_contents($originalImagePath, $originalImage);
 
        $powerMeter=new PixelCraft();
        $powerMeter->loadImage($originalImagePath);
        $powerMeter->cropRegion($controlRegion['x1'], $controlRegion['y1'], $controlRegion['x2'], $controlRegion['y2']);
 
        $powerMeterColorMap=$powerMeter->getColorMap(false);
        $sceneBrightness=0;
        $pixelCount=0;
        foreach ($powerMeterColorMap as $y => $x) {
            foreach ($x as $x => $color) {
                $pixelCount++;
                $sceneBrightness+=$powerMeter->rgbToBrightness($color);
            }
        }
 
        $sceneBrightness=round($sceneBrightness/$pixelCount,2);
 
        if ($debugMode) {
            $previewImage=new PixelCraft();
            $previewImage->loadImage($originalImagePath);
            $previewImage->setLineWidth(5);
            $regionPoints = array(
                $controlRegion['x1'], $controlRegion['y1'],
                $controlRegion['x1'] + $controlRegion['x2'], $controlRegion['y1'],
                $controlRegion['x1'] + $controlRegion['x2'], $controlRegion['y1'] + $controlRegion['y2'],
                $controlRegion['x1'], $controlRegion['y1'] + $controlRegion['y2']
            );
 
            $previewImage->drawPolygon($regionPoints, 'green');
            $previewImageBase64=$previewImage->getImageBase('jpeg', true);
 
            $base64CroppedImage=$powerMeter->getImageBase('jpeg', true);
 
            $debugOutput='';
            $debugOutput.='Scene brightness: '.$sceneBrightness.' Pixel count: '.$pixelCount.wf_tag('br');
            $debugOutput.= wf_img_sized($base64CroppedImage, '', '200').wf_tag('br');
            $debugOutput.= wf_img_sized($previewImageBase64, '', '900').wf_tag('br');
 
            deb($debugOutput);
        }
 
        if ($sceneBrightness>$powerAvailabilityThreshold) {
            $watchdogCallbackResult='генератор здається запущений';
            $generatorState=1;
        } else {
            $watchdogCallbackResult='генератор виглядає зупиненим';
        }
        } else {
            $watchdogCallbackResult='ERROR: отримано порожнє зображення';
        }
    } else {
        $watchdogCallbackResult='ERROR: не вдалося завантажити зображення з віддаленого хоста';
    }
 
    deb($watchdogCallbackResult);

Як відбувається аналіз сцени? Дуже просто. Зі сцени вирізається ось ця область, дбайливо підсвічена для візуальності в режимі відлагодження:

після чого міряється її загальний рівень яскравості

на основі чого робиться висновок

по швидкості, це власне займає приблизно аж стільки часу

Так, звичайно, ви можете вибрати будь-яку зону яка вас цікавить, наприклад

    $controlRegion=array(
        'x1'=>937,
        'y1'=>268,
        'x2'=>33,
        'y2'=>23
    );

ось якось так:

і відповідно визначати, чи є напруга в міській мережі

Звичайно, ніхто не заважає вам поміряти яскравість, тільки скажімо, в червоному каналі RGB, або ж організувати якийсь більш інтелектуальний аналіз чи OCR. Це обмежено тільки тим, чи не привернете ви уваги санітарів.