2016-08-19 136 views
0

我遇到了一些使用EmguCV從圖像中提取斑點的問題。我在網上看到的所有東西都使用Contours對象,但我想這已經從EmguCV3.0中刪除了?每次嘗試使用它時我都會遇到異常情況。我還沒有找到許多最新的/相關的SO主題,這些主題沒有過時。查找圖像中的最大斑點

基本上,我有一張葉子的照片。背景可能是白色,綠色,黑色等。我希望基本上移除背景,以便我可以在不干擾背景的情況下對葉子執行操作。我只是不知道我要去哪裏錯在這裏:

enter image description here

 Image<Bgr, Byte> Original = Core.CurrentLeaf.GetImageBGR; 
     Image<Gray, Byte> imgBinary = Original.Convert<Gray, Byte>(); 
     imgBinary.PyrDown().PyrUp(); // Smoothen a little bit 
     imgBinary = imgBinary.ThresholdBinaryInv(new Gray(100), new Gray(255)); // Apply inverse suppression 

     // Now, copy pixels from original image that are black in the mask, to a new Mat. Then scan? 
     Image<Gray, Byte> imgMask; 
     imgMask = imgBinary.Copy(imgBinary); 
     CvInvoke.cvCopy(Original, imgMask, imgBinary); 

     VectorOfVectorOfPoint contoursDetected = new VectorOfVectorOfPoint(); 
     CvInvoke.FindContours(imgBinary, contoursDetected, null, Emgu.CV.CvEnum.RetrType.List, Emgu.CV.CvEnum.ChainApproxMethod.ChainApproxSimple); 

     var contoursArray = new List<VectorOfPoint>(); 
     int count = contoursDetected.Size; 
     for (int i = 0; i < count; i++) 
     { 
      using (VectorOfPoint currContour = contoursDetected[i]) 
      { 
       contoursArray.Add(currContour); 
      } 
     } 

有了這個,我得到一個黑色圖像與白色線條點點。我已經來回絞盡腦汁,一直未能想出一些東西。任何指針將非常感激!

回答

-1

我建議你看看大津閾值。它爲您提供了一個門檻,您可以使用它將圖像分爲兩類(背景和前景)。使用OpenCV的閾值方法,您可以根據需要創建一個掩碼。

1
  1. 我認爲你需要找到哪一個是在每個輪廓上使用ContourArea的最大面積。
  2. 使用FillPoly找到需要填充的最大輪廓(因爲輪廓只是blob的投影圖,而不是所有像素),並創建一個遮罩,將其作爲值爲1的葉子像素和所有東西否則以0
  3. 最終使用面膜從原始圖像

提取葉像素,我不是在C#這樣精通,所以我在python附加一個代碼的OpenCV給你一些幫助。

所得圖像: enter image description here

希望這將是足夠的幫助。

import cv2 
import numpy as np 

# Read image 

Irgb = cv2.imread('leaf.jpg') 
R,G,B = cv2.split(Irgb) 

# Do some denosiong on the red chnnale (The red channel gave better result than the gray because it is has more contrast 
Rfilter = cv2.bilateralFilter(R,25,25,10) 

# Threshold image 
ret, Ithres = cv2.threshold(Rfilter,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU) 

# Find the largest contour and extract it 
im, contours, hierarchy = cv2.findContours(Ithres,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE) 

maxContour = 0 
for contour in contours: 
    contourSize = cv2.contourArea(contour) 
    if contourSize > maxContour: 
     maxContour = contourSize 
     maxContourData = contour 

# Create a mask from the largest contour 
mask = np.zeros_like(Ithres) 
cv2.fillPoly(mask,[maxContourData],1) 

# Use mask to crop data from original image 
finalImage = np.zeros_like(Irgb) 
finalImage[:,:,0] = np.multiply(R,mask) 
finalImage[:,:,1] = np.multiply(G,mask) 
finalImage[:,:,2] = np.multiply(B,mask) 
cv2.imshow('final',finalImage) 
+0

你能提供一些幫助,將其轉換爲C#嗎?我瞭解python,但我遇到了轉換爲C#的問題,以便將其中的一部分適應於我的應用程序。 – Jerry

+0

我只能幫助與c#中的opencv相關的東西。告訴我你會遇到麻煩,我會盡力幫助你。 –