2015-07-27 4 views
2

Я работаю с OpenCV 3.0 для Android. У меня есть изображение, в котором я хочу обнаружить угол рук внутри круглых дисков. для этого я работаю над HoughLinesP, чтобы обнаружить руки. Вот код.HoughLinesP не обнаруживает строки OpenCV android

Mat imgSource = new Mat(), imgCirclesOut = new Mat(),imgLinesOut=new Mat(); 
//grey opencv 
Imgproc.cvtColor(Image, imgSource, Imgproc.COLOR_BGR2GRAY); 
Imgproc.GaussianBlur(imgSource, imgSource, new Size(9, 9), 2, 2); 

int threshold = 0; 
int minLineSize = 0; 
int lineGap = 0; 

Imgproc.HoughLinesP(imgSource, imgLinesOut, 1, Math.PI/180, threshold, minLineSize, lineGap); 
for(int j = 0; i < imgLinesOut.cols(); i++) 
{ 
    double[] vec=imgLinesOut.get(0,j); 
    Point pt1, pt2; 
    pt1=new Point(vec[0],vec[1]); 
    pt2=new Point(vec[2],vec[3]); 
    Imgproc.line(Image, pt1, pt2, new Scalar(0,0,255), 3, Core.LINE_AA,0); 
} 

Но результат enter image description here

Что мне нужно, это угол руки в этих кругах. Любая помощь по этому вопросу высоко ценится. Заранее спасибо

Edit Я обновил свой код с этим

Mat imgSource = new Mat(), imgCirclesOut = new Mat(),imgLinesOut=new Mat(); 

Imgproc.GaussianBlur(Image, imgSource, new Size(5, 5), 2, 2);  
int threshold = 20; 
int minLineSize = 0; 
int lineGap = 10; 
Imgproc.Canny(imgSource, imgSource, 70, 100); 
Imgproc.HoughLinesP(imgSource, imgLinesOut, 1, Math.PI/180, threshold, minLineSize, lineGap); 
for(int j = 0; j < imgLinesOut.cols(); j++) 
{ 
    double[] vec=imgLinesOut.get(0,j); 

    Point pt1, pt2; 
    pt1=new Point(vec[0],vec[1]); 
    pt2=new Point(vec[2],vec[3]); 

    Imgproc.line(imgSource, pt1, pt2, new Scalar(0,0,255), 3, Core.LINE_AA,0); 
} 

как предложено @Micka, нет необходимости проседи изображения (я удалил cvtcolor). Я также уменьшил значение GuassianBlur Размер до 5. Я добавил Canny на изображение тоже для краев.

В результате размытия изображения

enter image description here

+0

вы попробовать 'Math.PI/1800'? – Micka

+0

@ Micka 'math.PI/1800' сдвинутая линия от последнего круга до второго ... –

+0

Ваша проблема, вероятно, в этой строке:' for (int j = 0; i Micka

ответ

3

Обнаружение линий может быть проблемой в таких маленьких изображений, так как у вас должно быть несколько точек, чтобы правильно заполнить аккумулятор Hough.

Я предлагаю использовать другой подход:

  1. сегмент каждый круг (коммутируемый)
  2. Extract самый большой темный блоб (рука)

Ниже приводится простая реализация этой идеи. Код находится на C++, но вы можете легко переносить на Java или, по крайней мере, использовать его в качестве ссылки.

#include "opencv2/opencv.hpp" 
using namespace cv; 

int main(int, char**) 
{ 
    Mat1b img = imread("path_to_image", IMREAD_GRAYSCALE); 

    Mat3b res; 
    cvtColor(img, res, COLOR_GRAY2BGR); 

    // Find dials 
    vector<Vec3f> circles; 
    HoughCircles(img, circles, CV_HOUGH_GRADIENT, 1, img.cols/10, 400, 40); 

    // For each dial 
    for (int i = 0; i < circles.size(); ++i) 
    { 

     // Segment the dial 
     Mat1b dial(img.size(), uchar(255)); 
     Mat1b mask(img.size(), uchar(0)); 
     circle(mask, Point(circles[i][0], circles[i][1]), circles[i][2], Scalar(255), CV_FILLED); 
     img.copyTo(dial, mask); 

     // Apply threshold and open 
     Mat1b bin; 
     threshold(dial, bin, 127, 255, THRESH_BINARY_INV); 
     Mat kernel = getStructuringElement(MORPH_ELLIPSE, Size(5,5)); 
     morphologyEx(bin, bin, MORPH_OPEN, kernel); 

     // Get min area rect 
     vector<Point> points; 
     findNonZero(bin, points); 
     RotatedRect r = minAreaRect(points); 

     // Draw min area rect 
     Point2f pts[4]; 
     r.points(pts); 
     for (int j = 0; j < 4; ++j) { 
      line(res, pts[j], pts[(j + 1) % 4], Scalar(0, 255, 0), 1); 
     }  
    } 

    imshow("Result", res); 
    waitKey(); 

    return 0; 
} 

Начиная с этого изображения:

enter image description here

Я нахожу руки здесь:

enter image description here

+0

Спасибо @Miki, Your решение работало. Мне пришлось удалить «CircleHough» и маскировать часть. Прикладной порог и открытое изображение, получение контуров и обход вокруг этого объекта сделали трюк. Еще раз спасибо :) –

+0

Это хорошее начало, чтобы прочитать показания счетчика для моего проекта https://stackoverflow.com/questions/45215212/read-a-gauge-meter-in-python, но только вопрос: как мне читать «значение» датчика? благодаря! – Michelangelo

-1
for(int j = 0; j < imgLinesOut.size(); j++) 

Это даст размер vector.To итерацию по этому вектору

Смежные вопросы