2016-08-19 90 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相关的东西。告诉我你会遇到麻烦,我会尽力帮助你。 –