2017-08-30 91 views
0

我现在正在研究液滴生成器,并且要计算它生成的液滴数量和液滴直径。我首先将灰度图像转换成二进制图像,然后从中提取特征,然后开始计算液滴。我在此附上我的图像,在这里你可以看到液滴呈圆圈形式,里面有另一个圆圈。所以,我的程序将它算作两滴。但我不希望液滴内的圆圈被视为物体。由于我是python和OpenCV的新手,我尝试了很多搜索,没有找到任何有用的东西。如果有人能提供帮助,这将非常好。我正在添加原始图片。看看这可能是有用的帮助。Python - 在计算对象时移除另一个圆圈内的圆圈

而不喷嘴液滴图像:

enter image description here

提取的图像:

enter image description here

另外的代码是:

image_subtracted = image-image_calibration 
     if showImages == 1: 
     print('image_subtracted') 
     print(image_subtracted) 
     fig3 = plt.figure(3) 
     fig3.suptitle('pure subtracted image') 
     plt.imshow(image_subtracted, cmap='Greys_r', interpolation='none') 
     plt.draw() 
     plt.waitforbuttonpress() 


#1.3To precisely show only the droplet 
image_subtracted[0:line_lowerNozzleEdge][:]=0 

image_subtracted=image_subtracted[line_lowerNozzleEdge+1:][:] 
image_subtracted=image_subtracted.astype('uint32') 

image_tmp=image_subtracted 
kernel = np.ones((5,5),np.uint8) 


image_tmp = ndimage.grey_erosion(image_tmp, size=(6,6)); 
image_tmp = ndimage.grey_dilation(image_tmp, size=(6,6)) 

image_subtracted=image_tmp 

if showImages == 1: 
    print('max(image_subtracted) = '+str(np.max(image_subtracted))) 
    fig4 = plt.figure(4) 
    fig4.suptitle('subtracted image') 
    plt.imshow(image_subtracted, cmap='Greys_r') 
    plt.draw() 
    plt.waitforbuttonpress() 
    plt.pause(0.5) 


#2.BINARIZE THE IMAGE 


thresh_rc = mh.thresholding.rc(image_subtracted) #Hmm! 

thresh_median = np.median(image_subtracted) 

thresh=thresh_rc 

image_binary = image_subtracted > thresh 

image_bin_int=image_binary.astype('uint8') 

if showImages == 1: 
    print('mh-tresholding: '+str(thresh_rc)) 
    print('median tresholding: '+str(thresh_median)) 
    print('used tresh: '+str(thresh)) 
    fig6 = plt.figure(6) 
    fig6.suptitle('binary image') 
    fig6 = plt.figure(6) 
    plt.imshow(image_binary, cmap=plt.cm.gray, interpolation='none') 
    plt.draw() 
    plt.waitforbuttonpress() 

    #3.EXTRACT THE FEATURES 
    image_tmp=image_bin_int 
    image_tmp = ndimage.grey_erosion(image_tmp, size=(6,6)); 
    image_tmp = ndimage.grey_dilation(image_tmp, size=(10,10)) 
    image_extracted=image_tmp 
    if showImages == 1: 
    fig7 = plt.figure(7) 
    plt.clf() 
    fig7.suptitle('image extracted') 
    plt.imshow(image_extracted, cmap=plt.cm.gray, interpolation='none') 
    plt.draw() 
    plt.waitforbuttonpress() 



T = mh.thresholding.otsu(image_extracted.astype('uint8')) 
labeled,nr_objects = mh.label(image_extracted.astype('uint8') > T) 
print('number of detected objects = '+str(nr_objects)) 
label_array=np.array(labeled).ravel() 
label_array=np.sort(label_array)  
pixel_sum=np.zeros(nr_objects+1) 

for ii in range(1,nr_objects+1,1): 
    n_tmp=np.where(label_array==ii)[0] 
    pixel_sum[ii]=len(n_tmp) 

ObjectArea=pixel_sum*pixelArea 
#assumption of a circle: 
Radius=np.sqrt(ObjectArea/np.pi) 
Diameter=2*Radius 
print(' ') 
print('object diameters in um ='+str(Diameter/1e-6)) 
print(' ') 
print(' ') 

if showImages == 1: 
    fig9 = plt.figure(9) 
    plt.clf() 
    plt.imshow(labeled, cmap=plt.cm.gray, interpolation='none') 
    plt.draw() 
    plt.waitforbuttonpress() 

return Diameter 
+0

一旦反转图像和计数。我想这是计数白色背景和内部白色作为两个对象。另外,你能把原始图像放一次吗?还有你如何从二进制文件中提取功能?这可能有助于 –

+2

为什么在没有使用OpenCV函数时标记为OpenCV?你有没有OpenCV可用? –

+0

我已添加原始图片。另外,是的,我有OpenCV使用。 –

回答

0

我用C++编写,但你可以轻松地移植我t到python。

int main(int argc, char** argv) 
{ 
    // read image 
    Mat src = imread("image.png"),dst; 

    // convert to gray 
    cvtColor(src, dst, COLOR_BGR2GRAY); 
    // binarize the image by thresholing 
    threshold(dst, dst, 30, 255, cv::THRESH_BINARY); 

    // get erosion kernel size 
    int morph_size = 3; 
    Mat el = getStructuringElement(MORPH_ELLIPSE, Size(4*morph_size + 1, 2*morph_size+1)); 

    // erode image to fill the empty gaps and make it more connected 
    erode(dst, dst, el); 

    // holds the contour points of all the objects in the image 
    std::vector<std::vector<Point> > v; 
    // holds the heirarchy 
    std::vector<Vec4i> hierarchy; 
    // find contours 
    findContours(dst, v, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0)); 

    std::cout<<"Number of shapes:" <<v.size()<<std::endl; 

    // draw the contours back to original image 
    drawContours(src, v, 1, Scalar(0,255,0),3,8, hierarchy, 0, Point()); 

    namedWindow("result"); 
    imshow("result", src); 
    waitKey(0); 
} 

二进制图像:

enter image description here

轮廓原始图像上描绘:

enter image description here