首页 > 编程语言 > 详细

python+opencv切割细胞及细胞团

时间:2020-03-19 14:50:50      阅读:290      评论:0      收藏:0      [点我收藏+]

从大图上获取细胞及细胞团坐标

持续更新……

import os,time
import cv2
import numpy as np
import matplotlib.pyplot as plt
import copy

def get_fit_img(img):
    dst = cv2.fastNlMeansDenoising(img,None,15,7,21)
    return dst

def get_mean(temp, long_=10):
    temp_1 = []
    for m in range(0+long_, 255-long_):
        temp_1.append(temp[m-long_:m+long_].mean())
    temp_2 = np.array(temp_1)
    temp_out = np.zeros(255)
    temp_out[0+long_: 255-long_] = temp_2
    return temp_out

def grien_value(temp):
    temp_1 = np.zeros(255)
    temp_1[1:255] = temp[0:254]
    temp_out = temp - temp_1
    temp_out = get_mean(temp_out, 10)
    return temp_out

def get_last2value(temp):
    sign1 = 0
    sign2 = 0
    cnt = 0
    value = 0
    temp_4 = temp[::-1]
    for k in range(0, len(temp_4)-1):
        if temp_4[k+1] > temp_4[k]:
            sign2 = sign1
            sign1 = 1
            if sign1 != sign2:
                cnt = cnt + 1
        else:
            sign2 = sign1
            sign1 = 0
            if sign1 != sign2:
                cnt = cnt + 1
        if cnt == 3:
            value = k
            break #!!!!!!!!!
    return 255-value

def get_2value(img, long_ = 10):
    temp_2 = cv2.calcHist([img],[0],None,[256],[0,256])
    temp_4 = get_mean(temp_2, long_)
    temp_4 = get_mean(temp_4, 5)
    temp_4 = grien_value(temp_4) #使用二阶导数更容易检测到细胞核像素阈值
#    plt.figure("Image")
#    plt.imshow(img)
#    plt.figure("Image_value")
#    plt.plot(temp_4)
#    plt.figure("Image_value_gre")
#    plt.plot(grien_value(temp_4))
#    plt.figure("Image_value_gre2")
#    plt.plot(grien_value(grien_value(temp_4)))
#    plt.show()
    sign1 = 0
    sign2 = 0
    cnt = 0
    value_1 = 0
    value_2 = 0
    for k in range(0, len(temp_4)-1):
        if temp_4[k+1] > temp_4[k]:
            sign2 = sign1
            sign1 = 1
            if sign1 != sign2:
                cnt = cnt + 1
        else:
            sign2 = sign1
            sign1 = 0
            if sign1 != sign2:
                cnt = cnt + 1
        if cnt == 3:
            value_1 = k
            break #!!!!!!!!!
            #print(temp_4[k])
    value_2 = get_last2value(temp_4)
    return value_1,value_2

def get_img_open(img,fit):
    img_open = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel_1)
    return img_open

def get_img_close(img,fit):
    img_close = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel_1)
    return img_close

# 获得细胞坐标
def get_cells(img, value, fit, limit_up, limit_down, side=5):
    ret_, thresh = cv2.threshold(img, value, 255, cv2.THRESH_BINARY_INV)
    thresh = get_img_open(thresh,fit) #过滤杂质
    image_, contours, hierarchy_ = cv2.findContours(thresh,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
    cells_xoy = []
    for cnt in range(0,len(contours,)):
        area = cv2.contourArea(contours[cnt])
        x,y,w,h=cv2.boundingRect(contours[cnt])
        [x_,y_] = img.shape
        x1 = max(x-side,0) #向外扩展5个像素
        x2 = min(x+w+side,x_)
        y1 = max(y-side,0)
        y2 = min(y+h+side,y_)
        cell_xoy = [x1,y1,x2,y2]
        if area > limit_down and area < limit_up and w/h < 2 and w/h >1/2: #默认细胞长宽比在0.5~2之间浮动
            cells_xoy.append(cell_xoy)
    return cells_xoy

# 获得细胞团坐标
def get_clusters(img, value, fit, limit_down, side=5):
    ret_, thresh = cv2.threshold(img, value, 255, cv2.THRESH_BINARY_INV)
    thresh = get_img_close(thresh,fit) #将密集的点连接成片
    fit2 = fit*0.1
    thresh = get_img_open(thresh,fit2) #过滤孤立的点
    image_, contours, hierarchy_ = cv2.findContours(thresh,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
    clusters_xoy = []
    for cnt in range(0,len(contours,)):
        area = cv2.contourArea(contours[cnt])
        x,y,w,h=cv2.boundingRect(contours[cnt])
        [x_,y_] = img.shape
        x1 = max(x-side,0)
        x2 = min(x+w+side,x_)
        y1 = max(y-side,0)
        y2 = min(y+h+side,y_)
        cluster_xoy = [x1,y1,x2,y2]
        if area > limit_down:
            clusters_xoy.append(cluster_xoy)
    return clusters_xoy

if __name__ == "__main__":
    dstroot = fovs
    list_dst = os.listdir(dstroot)
    for n in list_dst:
        imgpath = os.path.join(dstroot, n)
        print(imgpath)
        img_org = cv2.imread(imgpath)
        img_gray = cv2.imread(imgpath,0)
        cv2.imwrite(abc.png, img_gray)
        img_gray_fit = get_fit_img(img_gray)
        value_1,value_2 = get_2value(img_gray_fit) # 获取细胞核、背景阈值
        kernel_1 = np.ones((50,50),np.uint8)
        kernel_2 = np.ones((101,101),np.uint8)
        cells_xoy = get_cells(img_gray_fit, value_2, kernel_1, 20000, 1600, side=5)
        clusters_xoy = get_clusters(img_gray_fit, value_1, kernel_2, 50000, side=5)

 

python+opencv切割细胞及细胞团

原文:https://www.cnblogs.com/niulang/p/12524001.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!