2015-05-27 6 views
1

Я пытаюсь получить набор точек, находящихся в середине этой кривой. я найти этот сценарий, но с моим лазером изображение не работает ...opencv и python - Обнаружение лазерной изогнутой линии

im_gray = cv2.imread(img, cv2.CV_LOAD_IMAGE_GRAYSCALE) 

     im_gray = cv2.Canny(im_gray,50,150,apertureSize = 3) 

     ret, im_bw = cv2.threshold(im_gray, 0, 255, cv2.THRESH_BINARY) 

     #(thresh, im_bw) = cv2.threshold(im_gray, 128, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU) 

     #thresh = 127 
     #im_bw = cv2.threshold(im_gray, thresh, 255, cv2.THRESH_BINARY)[1] 

     #ret, bw = cv2.threshold(im_bw, 0, 255, cv2.THRESH_BINARY) 

     cv2.imwrite('resultpoint_bw.png',im_bw) 

     # find contours of the binarized image 
     contours, heirarchy = cv2.findContours(im_bw, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) 
     # curves 
     curves = np.zeros((im_bw.shape[0], im_bw.shape[1], 3), np.uint8) 

     cv2.imwrite('resultpoint_bw_2.png',im_bw) 


     for i in range(len(contours)): 

      # for each contour, draw the filled contour 
      draw = np.zeros((im_bw.shape[0], im_bw.shape[1]), np.uint8) 
      cv2.drawContours(draw, contours, i, (255,255,255), -1) 
      # for each column, calculate the centroid 
      for col in range(draw.shape[0]): 
       M = cv2.moments(draw[:, col]) 
       if M['m00'] != 0: 
        x = col 
        y = int(M['m01']/M['m00']) 
        curves[y, x, :] = (0, 0, 255) 


     cv2.imwrite('resultpoint_0.png',curves) 

в результате изображении на Poit неверен becouse является Контурами и не нуждаются в Контурах, но точка в аббревиатуре середины. ..

есть ли возможность сделать это?

+1

Почему эти помеченные 'java' и' C++ '? – EdChum

+0

becouse я ошибаюсь :) Мне нужно только pyton, C++ и opencv tag –

+0

вы можете добавить свои образцы изображений? –

ответ

0

Вы можете применить эти простые шаги, чтобы получить эту осевую линию.

  1. Порог двоичное Inverted
  2. Применить Thinning algorithm, чтобы уменьшить толщину.
  3. Найдите ненулевые пиксели в двоичном изображении.

void thinningIteration(Mat& im, int iter) 
    { 
     Mat marker = Mat::zeros(im.size(), CV_8UC1); 
     for (int i = 1; i < im.rows-1; i++) 
     { 
      for (int j = 1; j < im.cols-1; j++) 
      { 
       uchar p2 = im.at<uchar>(i-1, j); 
       uchar p3 = im.at<uchar>(i-1, j+1); 
       uchar p4 = im.at<uchar>(i, j+1); 
       uchar p5 = im.at<uchar>(i+1, j+1); 
       uchar p6 = im.at<uchar>(i+1, j); 
       uchar p7 = im.at<uchar>(i+1, j-1); 
       uchar p8 = im.at<uchar>(i, j-1); 
       uchar p9 = im.at<uchar>(i-1, j-1); 

       int A = (p2 == 0 && p3 == 1) + (p3 == 0 && p4 == 1) + 
         (p4 == 0 && p5 == 1) + (p5 == 0 && p6 == 1) + 
         (p6 == 0 && p7 == 1) + (p7 == 0 && p8 == 1) + 
         (p8 == 0 && p9 == 1) + (p9 == 0 && p2 == 1); 
       int B = p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9; 
       int m1 = iter == 0 ? (p2 * p4 * p6) : (p2 * p4 * p8); 
       int m2 = iter == 0 ? (p4 * p6 * p8) : (p2 * p6 * p8); 

       if (A == 1 && (B >= 2 && B <= 6) && m1 == 0 && m2 == 0) 
        marker.at<uchar>(i,j) = 1; 
      } 
     } 
     im &= ~marker; 
    } 

    void thinning(Mat& im) 
    { 
     im /= 255; 
     Mat prev = Mat::zeros(im.size(), CV_8UC1); 
     Mat diff; 
     do 
     { 
      thinningIteration(im, 0); 
      thinningIteration(im, 1); 
      absdiff(im, prev, diff); 
      im.copyTo(prev); 
     } 
     while (countNonZero(diff) > 0); 

     im *= 255; 
    } 

    void main() 
    { 
     Mat mSource_Bgr,mSource_Gray,mThreshold,mThinning; 
     mSource_Bgr= imread(FileName_S.c_str(),IMREAD_COLOR); 
     mSource_Gray= imread(FileName_S.c_str(),0); 

     threshold(mSource_Gray,mThreshold,50,255,THRESH_BINARY); 

     mThinning= mThreshold.clone(); 

     thinning(mThinning); 

     imshow("mThinning",mThinning); 

enter image description here

 vector<Point2i> locations; // output, locations of non-zero pixels 
     findNonZero(mThinning, locations); 

     for (int i = 0; i < locations.size(); i++) 
     { 
      circle(mSource_Bgr,locations[i],2,Scalar(0,255,0),1); 
     } 

     imshow("mResult",mSource_Bgr); 

enter image description here

} 
+0

Большое вам спасибо! теперь мне нужно преобразовать ваш скрипт в python. можно извлечь координату? –

0

Я нашел решение в Python:

import cv2 
    import numpy as np 
    import glob 
    import json, io 
    from matplotlib import pyplot as plt 
    from PIL import Image 

    img = cv2.imread(fname, 0); 

    i = Image.fromarray(self.__imgremapped_bw) 

    pixels = i.load() # this is not a list 

    self.__pointsData = []; 

    find = 0 

    for y in range(self.__top,self.__bottom): 
     row_averages = [] 
     for x in range(self.__top,self.__bottom): 
      cur_pixel = pixels[x, y] 
      if cur_pixel >= self.__thresholdColor: 
       row_averages.append(x) 
       find = 1 
      elif find == 1: 
       pointSum = 0 
       for idx, val in enumerate(row_averages): 
        pointSum += row_averages[idx]; 

       xf = pointSum/len(row_averages) 
       # 0.5 correzione pixel al centro 
       self.__pointsData.append([[y+0.5,xf+0.5]]) 
       row_averages = [] 
       find = 0 

    #self.__drawPoint(self.__imgremapped_bw) 

    return self.__pointsData 

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

собственной .__ pointsData.append ([[у + 0,5, + 0,5 XF]])

+0,5 является исправление, чтобы иметь центральный пиксель.

В этом случае можно иметь больше линии becouse в этой линии:

  if cur_pixel >= self.__thresholdColor: 
       row_averages.append(x) 
       find = 1 
      elif find == 1: 
       pointSum = 0 
       for idx, val in enumerate(row_averages): 
        pointSum += row_averages[idx]; 

       xf = pointSum/len(row_averages) 
       # 0.5 correzione pixel al centro 
       self.__pointsData.append([[y+0.5,xf+0.5]]) 
       row_averages = [] 
       find = 0 

существует медиа вычисления точек с цветовой гаммой.

Надеюсь, это поможет.

Thanks

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