Что будет если смешать орехи, Arduino, OpenCV и Delphi. Часть 1

    Привет, хабровчанин.

    Писатель из меня не очень, на это неоднократно указывали мне учителя в школе после прочтения моих сочинений. Не то что что-бы суть не была изложена, меня упрекали в сухости и лаконичности повествования. Тогда мне это казалось придирками, ведь лаконичность — это замечательно. Но не для писателя. В этот раз я попытаюсь исправится, ведь с того времени прочитаны тонны сайфая. Такова преамбула, и не исключено, что осиливший этот текст до конца всплакнет кровавой слезой, но я предупредил.

    Удосужилось мне счастливо жить в небольшом городке в центральной Украине. Причины сего мне не известны, но каждую осень колхозный рынок превращается в биржу по торговле грецким орехом, его везут со всей округи. Все покупают и продают как одетый так и раздетый орех. Ажиотаж затрагивает как профессиональных перекупщиков, так и пенсионеров, мне при этом почему-то вспоминаются голландские тюльпаны. Но история началась летом.

    С моим кумом мы владеем небольшим компьютерным магазинчиком, где он продает, а я занимаюсь мелким ремонтом и программированием. В очередной раз приехав с недельного отдыха с палатками на берегу реки, загоревший и нарыбачившийся вдоволь я сидел и что-то паял в своем кабинете, который я лаского зову «склеп» по причине обилия мертвого железа и постоянной температуры окружающей среды.

    — К тебе пришли.

    Я вышел из склепа и познакомился с парнем немного старше меня по имени Андрей. На ладони у него были половинки ядер грецкого ореха, одно темно-коричневое, почти черное, другое — светлое, практически бежевое. Андрей предложил работу, нужно было программно отделять первые от вторых. Это была первая ошибка. Нет, не подумайте плохо, ошибка не в том, что он связался со мной, а в том что принес мне настолько разные примеры. Мне была дана полная свобода в плане платформ и реализаций. Хоть и было предложено использовать камеры, я их отбросил, ввиду, как мне тогда показалось, сложности реализации и ресурсоемкости такого подхода. В качестве сенсора был выбран датчик tcs3200 — преобразователь цвет->частота, такие часто используют в DIY проектах по сортировке чего-нибудь цветного. По даташиту датчик имел хорошие характеристики: имел по 16 фотодиодов каждого цвета(R/G/B) плюс отдельно 16 фотодиодов для белого цвета. Глубина чувствительности каждого канала была заметно выше 8 бит на канал, которые предлагает бытовая вебкамера. Первая версия устройства представляла собой картонную трубу от пищевой фольги с вырезанным окошком для датчика и подсветки. Данные с максимально-возможной скоростью передавались в виндовое приложение. Получалось около 600 замеров в секунду.

    image image
    Фото не мои, взяты с сети, фотографий первого прототипа, увы, не осталось. Сам же прототип был порван детьми, когда они (и прототип и дети) были оставлены без присмотра.


    На скриншоте приложения графики на черном фоне пришлось нарисовать в фотошопе по памяти. Далее все иллюстрации будут реальными.

    Орехи скользили поштучно по трубе, наклоненной на 45 градусов, и если данные с датчика отличались от фона (предварительно калиброванного) — фиксировался орех и его средневзвешенный цвет. По этому значению и сортировались орехи, признаю, довольно примитивный алгоритм, тем не менее он отменно работал.
    Скетч для Leonardo
    const int s0 = 12; // sensor pins
    const int s1 = 13;
    const int s2 = 11;
    const int s3 = 10;
    const int out = 9; // TCS230 output
    const int ejector = 7;
     
    int red = 0;
    int green = 0;
    int blue = 0;
    int white = 0;
    int comm = 0;
     
    void setup() {
      pinMode(s0, OUTPUT);
      pinMode(s1, OUTPUT);
      pinMode(s2, OUTPUT);
      pinMode(s3, OUTPUT);
      pinMode(out, INPUT);
      pinMode(ejector, OUTPUT);
    
      Serial.begin(9600);
       while (!Serial) {
        ; // wait for serial port to connect. Needed for Leonardo only
      }
      digitalWrite(s0, HIGH);
      digitalWrite(s1, HIGH);  //l
    }
     
    void loop() {
      if (Serial.available() > 0) {
        comm = Serial.read();
      }
      if (comm == 65) {
        getColor();
        Serial.write(lowByte(red));
        Serial.write(highByte(red));
        
        Serial.write(lowByte(green));
        Serial.write(highByte(green));
        
        Serial.write(lowByte(blue));
        Serial.write(highByte(blue));
        
        Serial.write(lowByte(white));
        Serial.write(highByte(white));
       
        delayMicroseconds(25);
      }
      if (comm == 66) {
        digitalWrite(ejector, HIGH);
        delayMicroseconds(10000);
        digitalWrite(ejector, LOW);
      }
      
      if (comm == 67) {
        Serial.end();
        Serial.begin(9600);
         while (!Serial) {
          ; // wait for serial port to connect. Needed for Leonardo only
         }
      }
      
    }
     
    void getColor() {
    
      digitalWrite(s2, LOW);
      digitalWrite(s3, LOW);
      red = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH);
    
      digitalWrite(s3, HIGH);
      blue = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH);
    
      digitalWrite(s2, HIGH);
      green = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH);
    
      digitalWrite(s3, LOW);
      white = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH);
    
    }
    


    imageimage
    Фотографии, где видно разницу между первыми и вторыми орехами.

    С теми сэмплами что дал мне Андрей работало все прекрасно и отделяло темные от светлых орехов с точностью в 95%. Какой же был эпик фэйл когда в следующий раз были принесены орехи с менее контрастными различиями. Поделка отказывалась различать орехи, ведь их средневзвешенный цвет был практически одинаков. Была предпринята попытка анализировать орехи по графикам время/насыщенность цвета, но это не дало желаемых результатов, датчик на таких скоростях прилично шумел. В результате чего было принято решение переходить на камеры.

    Но об этом во второй, заключительной части, будет интересней, обещаю.



    PS: Добавил скетч

    Обещанная вторая часть.
    • +10
    • 16,9k
    • 9
    Поделиться публикацией
    Ой, у вас баннер убежал!

    Ну. И что?
    Реклама
    Комментарии 9
      +14
      Вам бы лучше две части объединить, иначе совсем коротко, обрывисто и непонятно
        +2
        Вторая часть будет менее «художественной». И она еще не готова, жду видео с цеха, но скорей всего так и будет, объединю в одну статью. Спасибо за комментарий.
          +11
          И какой смысл был разделять статью на части? Данная «часть» тянет максимум на введение к статье, но никак не на статью целиком.

          Не нужно гнаться за плюсиками, тем более, что одна цельная и законченная статья принесет вам куда больше, чем два-три-четыре подобных «огрызка». Хотите добрый совет — спрячьте эту в черновики, а потом опубликуйте новую, большую и хорошую. А то ведь может так случиться, что следующую «часть» вам публиковать будет «не на что» (фигурально выражаясь).

          Всё вышесказанное — на правах «имхо».
            0
            Спасибо за совет, но мотивация разделения на части была другой. Это всего навсего «проба пера».
            0
            Было бы интересно взглянуть на «боевые» условия, в которых работает система.
            Вообще тут задача, по моему, должна просто решаться при помощи цветовой сегментации в HSV цветовом пространстве. Но, конечно, всегда есть тонкости)
              0
              Я пошел другим путем, вычисляется процент схожести с базой эталонных образцов, т.е. по сути ищутся «похожие» текстуры. Более подробно опишу алгоритм во второй части.
              +2
              Камеру нужно выбирать такую, в которой можно отключить автоподстройку яркости/контрастности.
              Более видимое отличие могут принести ИК или УФ спектр. Найдите такие камеры и сфотографируйте на них образцы. Естественно под ИК или УФ лампой соответсвенно.
              Удачи!
                0
                Используется PS3 eye camera, она выдает 187 FPS при 320x240. Но будет заменена на что-то промышленное
                0
                Меня похожие идеи посещали, только для сортировки картофеля. Правда, дальше изучения теории дело не пошло…

                Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                Самое читаемое