furry.cat 20 октября 2020

🎨 Распознавание цветов в браузере с tracking.js за 5 шагов

Использование технологии компьютерного зрения для распознавания цветов на изображениях и в видео с помощью библиотеки tracking.js

Решение множества задач машинного зрения (сегментация изображений, выделение объектов и лиц) основано на распознавании цвета. Благодаря JavaScript-библиотеке Tracking.js это можно делать прямо в браузере!

Чтобы разобраться, как работает этот плагин, мы создадим демо-приложение, в которое можно загрузить нужное изображение и выбрать цвет для распознавания.

В нем будет загрузчик файлов, превью картинки и колорпикер для указания искомого цвета. Также добавим настройку допустимого отклонения (tolerance) с помощью слайдера – эта опция непосредственно не входит в библиотеку, мы реализуем ее самостоятельно. Для максимального удобства добавлена пипетка, чтобы можно было брать цвет прямо с картинки.

Нажатие на кнопку Track color запускает алгоритм распознавания. Найденные области обводятся цветной рамкой.

Поиграть с приложением вы можете по ссылке.

Полный код со всеми ресурсами доступен на GitHub.

Реализация

Tracking.js – одна из самых простых в использовании библиотек компьютерного зрения с низким порогом вхождения. Другими словами, вы можете просто брать ее и сразу же делать удивительные вещи.

Шаг #1. Подключение ресурсов

Вы можете загрузить библиотеку tracking.js из github-репозитория:

        git clone https://github.com/eduardolundgren/tracking.js.git
    

или подключить npm-пакет:

        npm install tracking
    

Для оформления интерфейса нам также понадобятся:

  • jquery – популярная библиотека для манипуляции DOM-элементами;
  • color-picker – для создания колорпикера;
  • rangeslider.js – полифилл для элемента input type="range";
  • broiler.js – для создания пипетки.

Подключите файлы стилей и скриптов всех плагинов и библиотек любым удобным для вас способом, например, в секции head в html-файле:

index.html
        <html>
  <head>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
    <link rel="stylesheet" href="style/color-tracking.css">
    <link rel="stylesheet" href="style/color-picker.min.css">
    <link rel="stylesheet" href="style/range-slider.css">

    <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
    <script src='js/tracking-min.js'></script>
    <script src='js/color-picker.min.js'></script>
    <script src='js/rangeslider.min.js'></script>
    <script src='js/broiler.js'></script>
  </head>
    

Шаг #2. Создание интерфейса

Код HTML демо-приложения:

index.html
        <main>
    <div class="container mt-2">
        <div class="row">
            <div class="col-12 col-lg-4 col-md-6">
                <div class="row col-12 d-block p-0 m-0">
                        <strong class="d-block">Tracking colors</strong>
                        <div id="color-list" class="row color-list m-0"></div>
                        <hr class="d-block m-3">
                </div>

                <div class="row">
                    <div class="col-8">
                        <section id="color-picker"></section>
                        <div class="p-2">
                            <label for="tolerance" class="font-weight-bold">Tolerance:</label>
                            <input type="range" id="tolerance" name="tolerance" min="0" max="100" value="30" step="1">
                            <span class="rangeslider__tooltip" id ="range-tooltip"></span>
                        </div>
                    </div>
                    <div class="col-4">
                        <div id="color-picker-selected"></div>
                        <button id="add-color-button" class="btn btn-primary">Add color</button>
                    </div>
                </div>
            </div>
            <div class="col-12 offset-lg-1 col-lg-7 col-md-6">
                <div class="row">
                        <div class="col-7">
                            <input id="image-selector"  type="file">
                        </div>
                        <div class="col-5">
                            <button id="track-button" class="btn btn-dark float-right">Track color</button>
                        </div>
                </div>
                <hr class="m-3">
                <div class="row">
                    <div class="col-12">
                        <div class="row">
                                <div class="col-7">
                                    <strong class="ml-3">Image</strong>
                                </div>
                                <div class="col-5">
                                    <button id="clear-button" class="btn btn-dark float-right">Clear</button>
                                </div>
                        </div>
                        
                        <div class="col-12 p-0 tooltip" id="image-container">
                            <img id="selected-image" class="p-0 col-12" src="images/CMYK.jpg" />
                            <span class="tooltiptext">Click to pick color from image</span>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</main>
<script src='js/range-slider.js'></script>
<script src="js/color-tracking.js"></script>
    

Здесь также подключаются скрипты: range-slider.js и главный файл color-tracking.js.

Создание и инициализация слайдера параметра tolerance – файл range-slider.js:

js/range-slider.js
        const $element = $('input[type="range"]');
let $handle;

$element
  .rangeslider({
    polyfill: false,
    onInit: function() {
      $handle = $('.rangeslider__handle', this.$range);
      updateHandle($handle[0], this.value);
    }
  })
  .on('input', function() {
    updateHandle($handle[0], this.value);
  });

// Обновление значения в ползунке слайдера
function updateHandle(el, val) {
  el.textContent = val;
}
    

Шаг #3. Создание трекера

Чтобы начать использовать функциональность библиотеки tracking.js, нужно создать объект трекера с помощью конструктора и передать ему цвета для распознавания. По умолчанию предлагается набор из трех цветов: пурпурный (magenta), бирюзовый (cyan) и желтый (yellow).

js/color-tracking.js
        let regColors = ['magenta', 'cyan', 'yellow'];
let tracker = new tracking.ColorTracker(regColors);
    

Также можно дополнительно регистрировать любые другие цвета. Для этого предназначен метод API tracking.ColorTracker.registerColor:

color-tracking.js
        $("#add-color-button").click(async function () {
    let color = $('#color-picker-selected').css( "background-color" );
    regColors.push(color);
    let t = slider.value;
    tracking.ColorTracker.registerColor(color, function(r, g, b) {
        return getColorDistance(getRGB(color), {r: r, g: g, b: b}) < t
    });
    displayColorList(regColors, 'color-list');
});

function getColorDistance(target, actual) {
    return Math.sqrt(
      (target.r - actual.r) * (target.r - actual.r) +
      (target.g - actual.g) * (target.g - actual.g) +
      (target.b - actual.b) * (target.b - actual.b)
    );
}
    

Этот код отслеживает нажатие на кнопку «Добавить цвет» (Add color) и регистрирует в трекере выбранный в колорпикере цвет. Метод registerColor принимает два аргумента: собственно цвет и функцию сравнения, которая будет запускаться для каждого обнаруженного на картинке цвета. В этой функции мы будем вычислять "разницу" между целевым и найденным цветами и сравнивать ее с установленным значением параметра tolerance.

Другими словами, чем больше tolerance, тем больше диапазон цветов, которые будут считаться подходящими и попадут в выделение.

Метод displayColorList выводит все выбранные цвета. Его реализацию вы можете посмотреть в репозитории.

Шаг #4. События трекера

Когда трекер обнаружит искомые цвета на изображении, он выбросит событие track, на которое можно подписаться.

color-tracking.js
        tracker.on('track', function(event) {
    event.data.forEach(function(rect) {
        drawRect(rect.x, rect.y, rect.width, rect.height, rect.color);
    });
});


function drawRect(x, y, w, h, color){
    let rect = $('<div></div>');
    rect.addClass('rect');
    rect.css({
        border : '2px solid ' + color,
        width : w + 'px',
        height : h + 'px',
        left : (img.offsetLeft + x) + 'px',
        top : (img.offsetTop + y) + 'px'
    });
    $('#image-container').append(rect);
}
    

В объекте события хранятся координаты всех выбранных областей. Для каждой области также доступен цвет, которому она соответствует.

Получив эти данные, мы создаем прямоугольные контейнеры с указанными параметрами и помещаем их на превью (метод drawRect).

Шаг #5. Установка изображения

Теперь осталось только передать трекеру изображение, на котором нужно определить выбранные цвета. Для этого предназначен статический метод библиотеки track:

color-tracking.js
        tracking.track('#selected-image', tracker);
    

В него следует передать селектор целевого элемента img (также поддерживаются video и canvas) и экземпляр трекера.

Объединим весь код создания и запуска трекера при нажатии на кнопку Track color:

        $("#track-button").click(async function () {
    if($( ".rect" ).length){
        $( ".rect" ).remove();
    }
    let tracker = new tracking.ColorTracker(regColors);
    tracker.on('track', function(event) {
        event.data.forEach(function(rect) {
            drawRect(rect.x, rect.y, rect.width, rect.height, rect.color);
        });
    });
    tracking.track('#selected-image', tracker);
});
    

Сначала мы должны удалить все области, оставшиеся с предыдущего поиска. Затем придется создать экземпляр трекера с выбранными цветами, установить обработчик события track и передать изображение.

Всю дополнительную функциональность (выбор цвета с помощью пипетки, смена картинки, сброс результатов поиска) вы можете найти в репозитории приложения.

***

Кроме обнаружения цвета прямо в браузере (на изображениях и даже на видео), библиотека tracking.js может обнаруживать лица людей, но не распознавать их. Более подробную информацию вы найдете в документации.

Источники

МЕРОПРИЯТИЯ

Комментарии 0

ВАКАНСИИ

Middle Android Developer
Москва, от 250000 RUB до 300000 RUB
Unity-разработчик
Москва, от 60000 RUB до 100000 RUB
Unity 3D Engineer
по итогам собеседования

ЛУЧШИЕ СТАТЬИ ПО ТЕМЕ

BUG