如何在python开放式细胞学图像中检测形状

2024-03-28 17:33:29 发布

您现在位置:Python中文网/ 问答频道 /正文

我试着检测细胞学图像中的形态,得到了这个结果enter image description here我的输入图像是enter image description here,但是我的结果不太好谁能帮我??? 我的舞台是, 彩色图像由(COLORMAP_HOT) 转换为灰度图像 使用canny过滤器 查找计数 测试轮廓 我使用python3.5和opencv3

我的代码:

 #!/usr/bin/env python
 import cv2
import numpy as np
from pyimagesearch.shapedetector import ShapeDetector
import argparse
import imutils
from scipy import ndimage
import math
import matplotlib.pyplot as plt
 if __name__ == '__main__' :

im = cv2.imread("23.png")
#im_out = np.zeros((670, 543, 3), np.uint8);
#resized = imutils.resize(im, width=300)
#ratio = im.shape[0] / float(resized.shape[0])
#coloration
im_color = cv2.applyColorMap(im, cv2.COLORMAP_HOT)
imgg = im_color[:, :, 1]
#cv2.putText(im_color, colormap_name(k), (30, 180), cv2.FONT_HERSHEY_DUPLEX, 0.5, (255, 255, 255),1);
im_out = im_color
gray = cv2.cvtColor(im_color, cv2.COLOR_RGB2GRAY)

blurred = cv2.GaussianBlur(gray, (3, 3), 0)
canny = cv2.Canny(blurred, 120, 200)
kernel = np.ones((5,5),np.uint8)
#morph
dilation = cv2.dilate(canny,kernel,iterations = 1)
erosion = cv2.erode(dilation,kernel,iterations = 1)
dilation = cv2.dilate(erosion,kernel,iterations = 1)
erosion = cv2.erode(dilation,kernel,iterations = 1)    
blurred = cv2.GaussianBlur(erosion, (3, 3), 0)
canny = cv2.Canny(blurred, 200, 200)


cv2.imshow("dilation", dilation)
cv2.imshow("canny", canny)
cv2.imshow("erosion", erosion)
#(thresh, im_bw) = cv2.threshold(im_gray, 128, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
cv2.imshow("im_out", im_out);
cv2.imshow("gray ", gray);



#contour
cnts = cv2.findContours(canny, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if imutils.is_cv2() else cnts[1]
# loop over the contours
for c in cnts:
    M = cv2.moments(c)
    if(M["m00"]==0):M["m00"]=1

    cX = int((M["m10"] / M["m00"]))
    cY = int((M["m01"] / M["m00"]))


    #shape = detect(c)
    c = c.astype("float")

    c = c.astype("int")
    #cv2.drawContours(im, [c], -1, (0, 255, 0), 2)
    #cv2.putText(im, shape, (cX, cY), cv2.FONT_HERSHEY_SIMPLEX,0.5, (255,0,0), 2)
    area = cv2.contourArea(c)
    perimeter = cv2.arcLength(c,True)
    M = cv2.moments(c)

    # initialize the shape name and approximate the contour
    shape = " "
    peri = cv2.arcLength(c, True)
    approx = cv2.approxPolyDP(c, 0.05 * peri, True)
    (x, y, w, h) = cv2.boundingRect(approx)
    area = cv2.contourArea(c)
    radius = w/2
    if len(approx) == 3:
        shape = ""

    # if the shape has 4 vertices, it is either a square or
    # a rectangle
    elif len(approx) == 4:
        if (M['m00']==0):
           M['m00']=1
        cx = int(M['m10']/M['m00'])
        cy = int(M['m01']/M['m00'])
        # compute the bounding box of the contour and use the
        # bounding box to compute the aspect ratio
         #(x,y) be the top-left coordinate of the rectangle and (w,h) be its width and height.
        (x, y, w, h) = cv2.boundingRect(approx)
        print ("area",area,"perimeter",perimeter,"cx",cx,"cy",cy,"x",x,"y", y,"w", w, "h",h)
        #fichier.write("area",area,"perimeter",perimeter,"cx",cx,"cy",cy)
        print (sep="\n")
        ar = w / float(h)

        shape = "square" if ar >= 0.95 and ar <= 1.05 else "rectangle"
        cv2.drawContours(im, [c], -1, (255, 0, 0), 2)
        cv2.putText(im, shape, (cX, cY), cv2.FONT_HERSHEY_SIMPLEX,0.5, (255,0,0), 2)
    # if Cystine>6
    elif len(approx) == 6:
        if (M['m00']==0):
           M['m00']=1
        cx = int(M['m10']/M['m00'])
        cy = int(M['m01']/M['m00'])
        print ("area",area,"perimeter",perimeter,"cx",cx,"cy",cy)
        print (sep="\n")
        shape = "HEXA"

        cv2.drawContours(im, [c], -1, (255, 0, 0), 2)
        cv2.putText(im, shape, (cX, cY), cv2.FONT_HERSHEY_SIMPLEX,0.5, (255,0,0), 2)
    # otherwise, we assume the shape is a circle
    elif (abs(1 - (float(w)/h))<=2 and abs(1-(area/(math.pi*radius*radius)))<=0.2):
        if (M['m00']==0):
           M['m00']=1
        cx = int(M['m10']/M['m00'])
        cy = int(M['m01']/M['m00'])
        print ("area",area,"perimeter",perimeter,"cx",cx,"cy",cy)
        print (sep="\n")
        shape = "circle"
        cv2.drawContours(im, [c], -1, (255,0, 0), 2)
        cv2.putText(im, shape, (cX, cY), cv2.FONT_HERSHEY_SIMPLEX,0.5, (255,0, 0), 2)

# show the output image
    cv2.imshow("Image", im)



cv2.waitKey(0);

Tags: theimportifareacv2intcxshape