Tag: Робот манипулятор Arduino. Техническое зрение Цветовой фильтр

July 11, 2019 finereader No comments exist

Робот манипулятор. Собираем готовый проект

 

Программная часть готового проекта :

  • код для платы Arduino, получающей по COM-порту от компьютера пакет с тремя углами поворота серводвигателей
  • программа в среде Processing, работающая на ПК, которая сначала определяет координаты мишени (обрабатывая изображение с камеры), а затем рассчитывает углы для Arduino

 

 

Только для начала, было бы неплохо отработать всю систему без камеры, просто указывая координаты мышкой на экране. Для этого и предназначена вот эта программа для Processing. Работает с той же программой для Arduino.

July 11, 2019 finereader No comments exist

Робот манипулятор. Техническое зрение

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

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

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

Повесим веб-камеру над рабочей зоной, в Processing захватим видео с этой камеры.

Обработка в Processing будет представлять чтение изображения с камеры несколько раз в секунду, а затем выделения пикселей требуемого цвета. Найдя все подходящие пиксели, зная их координаты, определим “центр масс” всей фигуры – это и есть точка, целеуказание для робота.


/*Программа реализует захват изображения 
с камеры и определение объекта цветовым фильтром
в пространстве HSB (в нем намного удобнее сравнивать объекты,
чем в RGB-пространстве)
Выбор цвета для работы фильтра производится указанием
мыши на пиксель*/

import processing.video.*;

Capture cam;
   
   //Переменные для хранения выбранного цвета
   float huesel = 0.0; //Оттенок цвета
   float satsel = 0.0;
   float brsel = 0.0;
  
  //Переменные для расчета центра фигуры
  int ii=0; //счетчик найденных пикселей
  float sumX=0.0; //сумма Х-координат найденных пикселей выбранного цвета
  float sumY=0.0; //сумма Y-координат найденных пикселей выбранного цвета

int w=320; //640
int h=240; //480

void setup() {
  
  size(320, 240);
  //size(640, 480);
  String[] cameras = Capture.list();

  if (cameras == null) {
    println("Failed to retrieve the list of available cameras, will try the default...");
    cam = new Capture(this, w, h);
  } if (cameras.length == 0) {
    println("There are no cameras available for capture.");
    exit();
  } else {
    println("Available cameras:");
    printArray(cameras);
    
    //Интерфейс камеры с нужным разрешением(320х240)
   // cam = new Capture(this, cameras[9]);
    cam = new Capture(this, cameras[12]);
    cam.start();
  }
}

void draw() {
  //Захватываем изображение с камеры
  if (cam.available() == true) {
    cam.read();
  }
  
  //Выводим изображение в окно
  image(cam, 0, 0, width, height);
  
  //Пробегаем по всем пикселям изображения
  ii=0; sumX=0.0; sumY=0.0;
  for (int i=0;i<w;i+=1){
    for(int j=0; j<h;j+=1){
       //получаем цвет текущего пикселя
       color cc = get(i,j);
       //и переводим его в HSB-пространство
       float h = hue(cc);
       float s = saturation(cc);
       float br = brightness(cc);
       //Сравниваем тек. пиксель с выбранным с учетом 
       //некоторого допуска на отличие в цвете
        if (h<=(huesel+15) && h>=(huesel-15) &&
            s<=(satsel+15) && s>=(satsel-15) &&
            br<=(brsel+150) && br>=(brsel-150))
        {    
          //добавляем координату к общей сумме
          sumX+=i;
          sumY+=j;
          ii++;   
          //делаем найденный пиксель красным
          color cch = color(255,0,0);
          set(i,j,cch); //set(i,j-1,cch);set(i-1,j-1,cch);
        }

    }
  }
  
  //вычисляем центр фигуры из найденных пикселей
  float cX = sumX/ii;
  float cY = sumY/ii;
  
  //рисуем перекрестие
  strokeWeight(5);
  stroke(255,0,0);
  point(cX,cY);
    strokeWeight(1);
    line(cX,0,cX,height);
    line(0,cY,width,cY);
  
  //перевод координат в мм
  float cXmm = cX*167/320;
  float cYmm = cY*125/240;
  fill(230,0,0);
  text("X"+" "+cXmm,width-50,20);
  text("Y"+" "+cYmm,width-50,40);
  
  //Запись кадров
 //saveFrame("frames2/####.tiff");  
}

//обработчик указания мыши - захват цвета указанного пикселя
void mouseClicked(){
  color col = get(mouseX,mouseY);
  huesel = hue(col);
  satsel = saturation(col);
  brsel  = brightness(col);
}

 

Сама обработка захваченной картинки (функция draw() ) заключается в обходе всех пикселей в двойном цикле for. Внешний цикл по столбцам по координате Х экрана – перебираем все по счетчику i от нулевого до ширины экрана width.

Внутренний цикл по координате Y перебирает все пиксели данного столбца (выбранного во внешнем цикле) двигаясь по счетчику j от нулевой строки до height.

Получить цвет пикселя можно по его координатам на экране функцией get(i,j)

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

 

Функция mouseclicked() нужна для указания требуемого цвета.

Используемая кодировка цвета – HSB. В этой кодировке собственно оттенок цвета задан первым значением, по которому удобно сравнивать пиксели.

 

Центр фигуры определяется как отношение суммы координат точек к их числу.

 

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