2016-07-25 36 views
2

enter image description here樣本圖像檢測該圖像中的綠色行,並計算它們的長度

該圖像可以是在倍以上嘈雜其中多個對象從背景中進行干預。現在我正在使用各種使用RGB色彩空間的技術來檢測線條,但是當由於背景中的障礙而導致顏色發生變化時,它會失敗。我正在使用opencv和python。 我已經讀過,HSV更適合用於顏色檢測並已使用但尚未成功。 我無法找到此問題的通用解決方案。這方面的任何提示或線索都會有很大的幫助。

+0

我目前正在爲您的問題工作的代碼。你能提供另一張圖片嗎?這些圖像超級嘈雜。即使應用了噪音消除濾波器,仍然存在很多噪音。 – Tes3awy

+0

其實圖像可能會更嘈雜。如果你想我可以爲你提供更多的圖像。順便說一下,我注意到一件有趣的事情,當我將飽和度值增加到超過某個值(這個值在不同的圖像中是不同的),但噪聲仍然存在時,這些線條被刪除。可能是這樣的工作! – Abhyudai

+0

看,我會爲你今天發佈一個工作流程。如果有可能爲您提供代碼,我會的。但是如果我還沒有完成代碼,我會在稍後發佈。 – Tes3awy

回答

0

你應該使用這個事實,你知道你正在試圖通過使用行hough變換來檢測一條線。 http://docs.opencv.org/2.4/doc/tutorials/imgproc/imgtrans/hough_lines/hough_lines.html

  • 當障礙物也看起來像一個線路上使用,你大概知道什麼是綠線的方向的事實。
  • 如果你不知道的行使用興田事實方向,有幾個綠線與同方向只有一條線是障礙

這裏是我的意思代碼:

import cv2 
import numpy as np 

# Params 
minLineCount = 300 # min number of point alogn line with the a specif orientation 
minArea = 100 

# Read img 
img = cv2.imread('i.png') 
greenChannel = img[:,:,1] 

# Do noise reduction 
iFilter = cv2.bilateralFilter(greenChannel,5,5,5) 

# Threshold data 
#ret,iThresh = cv2.threshold(iFilter,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU) 
iThresh = (greenChannel > 4).astype(np.uint8)*255 

# Remove small areas 
se1 = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5)) 
iThreshRemove = cv2.morphologyEx(iThresh, cv2.MORPH_OPEN, se1) 

# Find edges 
iEdge = cv2.Canny(iThreshRemove,50,100) 

# Hough line transform 
lines = cv2.HoughLines(iEdge, 1, 3.14/180,75) 

# Find the theta with the most lines 
thetaCounter = dict() 
for line in lines: 
    theta = line[0, 1] 
    if theta in thetaCounter: 
     thetaCounter[theta] += 1 
    else: 
     thetaCounter[theta] = 1 

maxThetaCount = 0 
maxTheta = 0 
for theta in thetaCounter: 
    if thetaCounter[theta] > maxThetaCount: 
     maxThetaCount = thetaCounter[theta] 
     maxTheta = theta 

# Find the rhos that corresponds to max theta 
rhoValues = [] 
for line in lines: 
    rho = line[0, 0] 
    theta = line[0, 1] 
    if theta == maxTheta: 
     rhoValues.append(rho) 

# Go over all the lines with the specific orientation and count the number of pixels on that line 
# if the number is bigger than minLineCount draw the pixels in finaImage 
lineImage = np.zeros_like(iThresh, np.uint8) 
for rho in range(min(rhoValues), max(rhoValues), 1): 
    a = np.cos(maxTheta) 
    b = np.sin(maxTheta) 
    x0 = round(a*rho) 
    y0 = round(b*rho) 
    lineCount = 0 
    pixelList = [] 
    for jump in range(-1000, 1000, 1): 
     x1 = int(x0 + jump * (-b)) 
     y1 = int(y0 + jump * (a)) 
     if x1 < 0 or y1 < 0 or x1 >= lineImage.shape[1] or y1 >= lineImage.shape[0]: 
      continue 
     if iThreshRemove[y1, x1] == int(255): 
      pixelList.append((y1, x1)) 
      lineCount += 1 

    if lineCount > minLineCount: 
     for y,x in pixelList: 
      lineImage[y, x] = int(255) 

# Remove small areas 

## Opencv 2.4 
im2, contours, hierarchy = cv2.findContours(lineImage,cv2.RETR_CCOMP,cv2.CHAIN_APPROX_NONE) 

finalImage = np.zeros_like(lineImage) 
finalShapes = [] 
for contour in contours: 
    if contour.size > minArea: 
     finalShapes.append(contour) 

cv2.fillPoly(finalImage, finalShapes, 255) 
## Opencv 3.0 
# output = cv2.connectedComponentsWithStats(lineImage, 8, cv2.CV_32S) 
# 
# finalImage = np.zeros_like(output[1]) 
# finalImage = output[1] 
# stat = output[2] 
# for label in range(output[0]): 
#  if label == 0: 
#   continue 
#  cc = stat[label,:] 
#  if cc[cv2.CC_STAT_AREA] < minArea: 
#   finalImage[finalImage == label] = 0 
#  else: 
#   finalImage[finalImage == label] = 255 

# Show image 
#cv2.imwrite('finalImage2.jpg',finalImage) 
cv2.imshow('a', finalImage.astype(np.uint8)) 
cv2.waitKey(0) 

和用於圖像的結果: Result

enter image description here

+0

在識別線條之前,您正在使用OTSU打穀。如果線的強度小於OTSU閾值,線將被移除。此工作流程適用於此映像,但不適用於大多數其他示例。 – Abhyudai

+0

我用iThresh =(greenChannel> 10).astype(np.uint8)* 255等基本維持替換了OTSU閾值,它仍然有效。請張貼另一張硬盤圖片,讓我看看問題出在哪裏 –

+0

剛纔看到您添加了另一個示例,我將相應地修復我的代碼 –

0

仍在進行中

首先,RGB圖像由3個灰度圖像組成。既然你需要綠色,你只能處理一個通道。綠色的那個。爲此,您可以分割圖像,您可以使用b,g,r = cv2.split('Your Image')。如果你是顯示綠色通道,你會得到這樣的輸出:

green_channel

之後,你應該使用門檻所需的方式形象。在這種情況下,我更喜歡Otsu's thresholding。閾值後輸出爲:

thresholded_image

很明顯的是,閾值的圖像是extremley嘈雜。所以執行erosion會稍微降低噪音。該減噪圖像將是類似如下:

erosion

我嘗試使用closing代替dilation,但closing保留一些不必要的噪音。所以我分別執行erosion,然後是dilationdilation後輸出爲:

dilation

需要注意的是:你可以做你自己的方式在形態操作。您可以使用opening而不是我所做的。結果是從一個人到另一個人從 主觀。現在

你可以嘗試一個這兩種方法:

1.斑點檢測。 2. HoughLine變換。

TODO

試試這兩種方法,並選擇最好的。

+0

謝謝奧薩馬。我已經嘗試過這些技術,但是它的成功很少。如果您只考慮綠色部分,算法可以從背景中檢測綠色的東西。順便說一下,您是否考慮過我在先前的評論中提出的關於飽和度的觀點。 – Abhyudai

+0

@Abhyudai對不起,我沒有收到你的評論。我不太瞭解它。我在rgb色彩空間中對圖像進行了操作,因爲沒關係。您也可以將其轉換爲hsv,這將是一件好事。但是對於rgb來說,它爲什麼改變顏色空間。我有一個問題,我的答案是否有幫助。你到目前爲止嘗試過嗎?完成後我會完成答案。 – Tes3awy

+0

如果您僅使用綠色色彩空間,您不覺得背景中的物體(黃色(R + G))可能會妨礙您的工作流程嗎?你的回答沒有幫助,因爲我在發佈這個問題之前使用了這些技術。該解決方案可能適用於某些圖像,但我無法找到通用圖像。如果您願意,我可以爲您提供更多樣本。 – Abhyudai