Beispiel #1
0
def TraMapSag(sagPoints,traPath):
    r1, c1, o1, pixelSpacingXY, n1 = sagPoints
    orienta, pos, pixelSpa = dicom_metainfo(traPath,
                                            ['0020|0037', '0020|0032', '0028|0030'])
    (r2, c2), o2, pixelSpa = parse_orentation(orienta), parse_position(pos), parse_pixelSpacing(
        pixelSpa)
    image = dicom2array(traPath)
    srcHeigh, srcWidth = image.shape[:2]
    p1 = o2  # 左上角的点
    p2 = p1 + r2 * pixelSpa[0] * (srcWidth - 1)  # 右上角的点
    p3 = p2 + c2 * pixelSpa[1] * (srcHeigh - 1)  # 右下角的点
    p4 = p1 + c2 * pixelSpa[1] * (srcHeigh - 1)  # 左下角的点
    # 点到平面的距离
    # p1 O1
    dv1 = np.dot(p1 - o1, n1)
    # p2 O1
    dv2 = np.dot(p2 - o1, n1)
    # p3 O1
    dv3 = np.dot(p3 - o1, n1)
    # p4 O1
    dv4 = np.dot(p4 - o1, n1)

    iscross12 = ((dv1 > 0) & (dv2 < 0)) | ((dv1 < 0) & (dv2 > 0))
    iscross23 = ((dv2 > 0) & (dv3 < 0)) | ((dv2 < 0) & (dv3 > 0))
    iscross34 = ((dv3 > 0) & (dv4 < 0)) | ((dv3 < 0) & (dv4 > 0))
    iscross41 = ((dv4 > 0) & (dv1 < 0)) | ((dv4 < 0) & (dv1 > 0))
    if not (iscross12 | iscross23 | iscross34 | iscross41):
        return

    cps = []
    for iscross, (pv, pp), (ddv, ddp) in zip([iscross12, iscross23, iscross34, iscross41],
                                             [(p1, p2), (p2, p3), (p3, p4), (p4, p1)],
                                             [(dv1, dv2), (dv2, dv3), (dv3, dv4), (dv4, dv1)]):
        if not iscross:
            # 是否相交
            continue
            # 计算交点坐标  相似三角形?
        cp = [pv[i] + (pp[i] - pv[i]) * ddv / (ddv - ddp) for i in range(3)]
        cps.append(np.array(cp))
    # for cp in cps:
    #     # 看下算出来的点在不在定位图平面上 带入平面方程 正确应该是几乎等于0
    #     print(n1 * (cp - o1))

    assert len(cps) == 2
    coords = []
    coords_img = []
    for cp in cps:
        # 投影
        xmap = np.dot(cp - o1, r1) / np.linalg.norm(r1)
        ymap = np.dot(cp - o1, c1) / np.linalg.norm(c1)

        # 这个没什么用
        coords.append(np.array(xmap, ymap))
        # pixel坐标
        coords_img.append(np.array([int(xmap / pixelSpacingXY[0]), int(ymap / pixelSpacingXY[1])])) #得到映射到sag的两个点
    return coords_img
Beispiel #2
0
def SagKeyPoints(sagPath):
    image1 = dicom2array(sagPath)
    orienta, pos, pixelSpacingXY = dicom_metainfo(sagPath,
                                                  ['0020|0037', '0020|0032', '0028|0030'])
    (r1, c1), o1, pixelSpacingXY = parse_orentation(orienta), parse_position(pos), parse_pixelSpacing(
        pixelSpacingXY)

    srcHeigh, srcWidth = image1.shape[:2]
    n1 = np.cross(r1, c1)

    p1 = o1  # 左上角的点
    p2 = p1 + r1 * pixelSpacingXY[0] * (srcWidth - 1)  # 右上角的点
    p3 = p2 + c1 * pixelSpacingXY[1] * (srcHeigh - 1)  # 右下角的点
    p4 = p1 + c1 * pixelSpacingXY[1] * (srcHeigh - 1)  # 左下角的点

    return r1,c1,o1,pixelSpacingXY,n1
Beispiel #3
0
def to_Json(pointsPath, dataTestPath, Tojson=r"reslut_.json"):
    jsonFile = []

    identificationList = [
        "L5-S1", "L5", "L4-L5", "L4", "L3-L4", "L3", "L2-L3", "L2", "L1-L2",
        "L1", "T12-L1", "T12"
    ]
    f = open(pointsPath, 'r')
    datas = f.readlines()
    count = 0

    for data in datas:
        Temp = {
            "studyUid":
            "1.2.840.473.8013.20181026.1091511.864.22434.92",  # dicom study UID
            "data": [{
                "instanceUid":
                "1.3.46.670589.11.32898.5.0.16316.2018102610554807009",  # dicom instance UID
                "seriesUid":
                "1.3.46.670589.11.32898.5.0.16316.2018102610554554000",  # dicom series UID
                "annotation": [{
                    "data": [{
                        "annotator":
                        0,  # 可选
                        "point": [  # 关键点标注
                            {
                                "coord": [252, 435],  # 点的像素坐标
                                "tag": {
                                    "disc": "v2",  # 椎间盘类型膨出
                                    "identification": "L1-L2"  # 椎间盘定位L1-L2间椎间盘
                                },
                                "zIndex": 0,  # 第几个slice
                            },
                        ]
                    }],
                }]
            }]
        }
        jsonTemp = Temp
        d = data.split()
        ImgPath = d[0].split('/')[-1].split('.')[0].split('_')  #寻找dcm
        dicmPath = dataTestPath + '/' + ImgPath[0] + "/" + ImgPath[1] + '.dcm'
        studyUid, seriesUid, instanceUid, instanceNumber = readyData.dicom_metainfo(
            dicmPath, ['0020|000d', '0020|000e', '0008|0018', '0020|0013'])
        jsonTemp["studyUid"] = studyUid
        jsonTemp["data"][0]["instanceUid"] = instanceUid
        jsonTemp["data"][0]["seriesUid"] = seriesUid
        jsonTemp["data"][0]["annotation"] = []
        annotationDic = {}
        annotationDic["data"] = {}
        annotationDic["data"]["point"] = []

        if len(d) > 1:
            d = sortPoint(d)
            for index, target in enumerate(d):
                tagDic = {}
                point_dic = {}
                x, y, vd, c, p = target.split(',')
                # c = "v2"
                point_dic["coord"] = [int(x), int(y)]
                if vd == "disc":
                    if p == '1':
                        tagDic[vd] = c
                    else:
                        tagDic[vd] = c
                else:
                    tagDic[vd] = c
                # tagDic["p"] = p
                tagDic["identification"] = identificationList[index]
                point_dic["tag"] = tagDic
                point_dic["zIndex"] = instanceNumber
                annotationDic["data"]["point"].append(point_dic)
                if index == 11:
                    break

        jsonTemp["data"][0]["annotation"].append(annotationDic)
        jsonFile.append(jsonTemp)
        count += 1
    f.close()

    f1 = open(Tojson, "w")
    json.dump(jsonFile, f1)
    f1.close()

    print("json中数量:", count)
Beispiel #4
0
def metricDetect(yolo, truejson, testFile, sliceResize):
    with open(truejson, "r", encoding="utf-8") as f:
        truejsonTarge = json.loads(f.read())

    from classifycation import CNN

    cnn_disc = CNN(sliceResize)
    model_disc = cnn_disc.loadTestdisc()
    cnn_discv5 = CNN(sliceResize)
    model_discv5 = cnn_discv5.loadTestdiscv5()
    cnn_vertebra = CNN(sliceResize)
    model_vertebra = cnn_vertebra.loadTestvertebra()

    TruePointNum = 0
    TP = 0  #在目标内且 如果分类正确
    FP = 0  #在目标内且 分类错误 and 如果预测的点不落在任何标注点
    FN = 0  #标注点没有被任何预测点正确命中

    vertebraTP = 0
    vertebraFP = 0
    discTP = 0
    discFP = 0

    mm6c = 0
    mmc = 0
    count = 0
    study = os.listdir(testFile)
    for studyI in study:
        Impath = os.listdir(os.path.join(testFile, studyI))
        for Impathi in Impath:
            try:
                studyUid, seriesUid, instanceUid = dicom_metainfo(
                    os.path.join(os.path.join(testFile, studyI), Impathi),
                    ['0020|000d', '0020|000e', '0008|0018'])
                for studyid in truejsonTarge:
                    if studyUid == studyid["studyUid"] and seriesUid == studyid[
                            "data"][0]["seriesUid"] and instanceUid == studyid[
                                "data"][0]["instanceUid"]:
                        count += 1
                        image = dicom2array(
                            os.path.join(os.path.join(testFile, studyI),
                                         Impathi))

                        truepoints = studyid["data"][0]["annotation"][0][
                            "data"]["point"]
                        image = Image.fromarray(image)
                        image = image.convert("RGB")

                        r_image, points = yolo.detect_image(image)
                        #判断检测点与真实点

                        mean = np.mean(image)
                        std = np.mean(np.square(image - mean))
                        image = (image - mean) / np.sqrt(std)

                        image = np.asarray(image)
                        m, n, _ = image.shape

                        matchedIndex = []
                        for truepoint in truepoints:
                            mmc += 1
                            xt, yt = list(map(int, truepoint["coord"]))
                            tag = truepoint["tag"]
                            if "disc" in tag.keys():
                                ct = tag["disc"]
                            else:
                                ct = tag["vertebra"]

                            xy = sorted(points, key=lambda x: x[2])
                            deta = []
                            for i in range(len(xy) - 1):
                                deta.append(xy[i + 1][2] - xy[i][2])
                            deta = np.mean(deta)
                            print("deta:", deta)

                            for index, metricpoint in enumerate(points):
                                c, x, y = metricpoint

                                mm = 6
                                mm8 = 8
                                if x <= xt + mm and x >= xt - mm and y <= yt + mm and y >= yt - mm:  # 在标注点内
                                    matchedIndex.append(index)
                                    mm6c += 1
                                    TruePointNum += 1

                                    w1, h1 = m / 5, n / 20  # 椎间盘要求更长而不是更高  n控制高度
                                    offset = 5

                                    miny = y - deta
                                    maxy = y + deta
                                    minx = x + offset - w1 / 2
                                    maxx = x + offset + w1 / 2

                                    # nimg_x = image[int(miny):int(maxy), int(minx):int(maxx)]

                                    if "disc" in tag.keys():
                                        xlen2 = int(w1 / 2)
                                        X = dealImg(image, int(miny),
                                                    int(maxy),
                                                    int(minx) + int(xlen2),
                                                    int(maxx), sliceResize)

                                        X = X.reshape([1] + sliceResize + [1])

                                        p = model_disc.predict(X)
                                        pre = np.argmax(p, axis=1)
                                        pc = cnn_disc.disc_label[int(pre)]
                                        if pc == ct:
                                            TP += 1
                                            discTP += 1
                                        else:
                                            FP += 1
                                            discFP += 1
                                    else:
                                        w1, h1 = m / 5, n / 20  # 识别框的宽度和高度 更大
                                        offset = 0
                                        miny = y - h1  #- deta - offset
                                        maxy = y + h1  #+ deta + offset
                                        minx = x + offset - w1 / 2
                                        maxx = x + offset + w1 / 2

                                        # nimg_x = image[int(miny):int(maxy), int(minx):int(maxx)]
                                        # nimg_x = cv2.resize(nimg_x, (sliceResize[1], sliceResize[0]))[:, :, 1]
                                        X = dealImg(image, int(miny),
                                                    int(maxy), int(minx),
                                                    int(maxx), sliceResize)

                                        # plt.subplot(4, 5, int(1 + 5 * 1))
                                        # plt.imshow(X[:,:,0])
                                        # plt.show()

                                        X = X.reshape([1] + sliceResize + [1])
                                        p = model_vertebra.predict(X)
                                        pre = np.argmax(p, axis=1)
                                        pc = cnn_vertebra.vertebra_label[int(
                                            pre)]
                                        if pc == ct:
                                            TP += 1
                                            vertebraTP += 1
                                        else:
                                            FP += 1
                                            vertebraFP += 1
                                    break
                        FP += len(points) - len(matchedIndex)
            except:
                print("文件错误:",
                      os.path.join(os.path.join(dataPath, studyI), Impathi))
    print("总共点数:", mmc)
    print("TP/总定位:", TruePointNum / mmc, "TP/(TP+FP):", TP / (TP + FP + 1e-2))
    print("discTP/(TP+FP):", discTP / (discTP + discFP), "vertebraTP/(TP+FP):",
          vertebraTP / (vertebraTP + vertebraFP))
Beispiel #5
0
def step1(dataPath, jsondata, truejsonPath=None):
    '''
    将 图片 与 锚点对应
    :return:
    '''
    image = {}
    count = 0
    study = os.listdir(dataPath)
    for studyI in study:
        Impath = os.listdir(os.path.join(dataPath, studyI))
        # print("study:", studyI)
        for Impathi in Impath:
            try:
                studyUid, seriesUid, instanceUid, desc, idex = dicom_metainfo(
                    os.path.join(os.path.join(dataPath, studyI), Impathi), [
                        '0020|000d', '0020|000e', '0008|0018', '0008|103e',
                        "0020|0013"
                    ])
                for studyid in jsondata:
                    if studyUid == studyid["studyUid"] and seriesUid == studyid[
                            "data"][0]["seriesUid"] and instanceUid == studyid[
                                "data"][0]["instanceUid"]:
                        count += 1
                        image[studyI + "_" + Impathi] = dicom2array(
                            os.path.join(os.path.join(dataPath, studyI),
                                         Impathi))

                        # 在yolo.py中运行watchTest打开注释
                        img = dicom2array(
                            os.path.join(os.path.join(dataPath, studyI),
                                         Impathi))
                        # if studyI == seestudy:
                        plt.figure()
                        plt.title(studyI + "_" + Impathi + "\t" + desc + '\t' +
                                  idex)
                        plt.imshow(img)

                        if truejsonPath != None:
                            for studyid1 in truejsonPath:
                                if studyUid == studyid1[
                                        "studyUid"] and seriesUid == studyid1[
                                            "data"][0][
                                                "seriesUid"] and instanceUid == studyid1[
                                                    "data"][0]["instanceUid"]:
                                    truePoints = studyid1["data"][0][
                                        "annotation"][0]["data"]["point"]
                                    for point in truePoints:
                                        x, y = point['coord']
                                        print("True zIndex:", point["zIndex"])
                                        tag = point['tag']
                                        loc = tag['identification']

                                        if "disc" in tag.keys():
                                            k = tag["disc"]
                                        else:
                                            k = tag["vertebra"]
                                        # if studyI == seestudy:
                                        plt.scatter(x, y, s=12, c='g')
                                        plt.text(x=x + 5,
                                                 y=y - 5,
                                                 s=loc + '**' + k)

                        for point in studyid["data"][0]["annotation"][0][
                                "data"]["point"]:
                            x, y = point['coord']
                            # print("zIndex:",point["zIndex"] ," red")
                            tag = point['tag']
                            loc = tag['identification']

                            if "disc" in tag.keys():
                                k = tag["disc"]
                            else:
                                k = tag["vertebra"]
                            # if studyI == seestudy:
                            plt.scatter(x, y, s=6, c='r')
                            plt.text(x=x + 5, y=y, s=loc + '--' + k)
                        # if studyI == seestudy:
                        plt.show()
            except:
                print("文件错误:",
                      os.path.join(os.path.join(dataPath, studyI), Impathi))
Beispiel #6
0
def step1Test(dataPath,testTxt=None):
    '''
    在准备jpg时,首先先判断是否为T2_sag,只对T2_sag做定位识别
    target: t2sag:0, t1sag:1, t2tra:2
    :param dataPath:
    :return:
    '''
    count = 0
    study = os.listdir(dataPath)



    f = open(testTxt, 'r')
    datas = f.readlines()
    f.close()

    for data in datas:
        d = data.split()
        ImgPath = d[0].split('/')[-1].split('.')[0].split('_')  # 寻找dcm
        studyI = ImgPath[0]
        dicmPath = dataPath + '/' + ImgPath[0] + "/" + ImgPath[1] + '.dcm'  #answer中间帧
        Impath = os.listdir(os.path.join(dataPath, studyI)) #找到study下的所有dcm 为了寻找tra,同一标签下第一左边方差小
        describes2pos = {}
        describes2imgPathes = {}

        for Impathi in Impath:
            pos = dicom_metainfo(os.path.join(os.path.join(dataPath, studyI), Impathi), ['0020|0032'])[0]
            describ = dicom_metainfo(os.path.join(os.path.join(dataPath, studyI), Impathi), ['0008|103e'])[0]
            seriesNumber = dicom_metainfo(os.path.join(os.path.join(dataPath, studyI), Impathi), ['0020|0011'])[0]
            describ += seriesNumber
            if re.match(r"(.*)[sS][cC][oO][uU][tT](.*)", describ, 0): #不加入
                continue
            elif re.match(r"(.*)[sS][aA][gG](.*)",describ,flags=0) or re.match(r"(.*)[sS][aA][gG](.*)",describ,0):
                continue
            else:
                if describ not in describes2pos.keys():
                    describes2pos[describ] = [parse_position(pos)[0]]
                    describes2imgPathes[describ] = [Impathi]
                else:
                    describes2pos[describ].append(parse_position(pos)[0])
                    describes2imgPathes[describ].append(Impathi)
        describes2posN = {}
        describes2imgPathesN = {}
        flagN = False
        for key, value in describes2pos.items():
            if re.match(r"(.*)[tT][rR][aA](.*)",key,flags=0):
                flagN = True
                describes2posN[key] = value
                describes2imgPathesN[key] = describes2imgPathes[key]
        if flagN:
            describes2pos = describes2posN
            describes2imgPathes = describes2imgPathesN
        plt.figure(1)
        imgSAG = dicom2array(dicmPath)
        plt.imshow(imgSAG)

        sagPoints = SagKeyPoints(dicmPath)
        index = 0
        for key,value in describes2pos.items():
            if np.std(np.array(value))<10 and len(value) > 6:
                # plt.figure(2)
                print("找到tra! -- ",studyI,key," -- ",len(value))
                count += 1
                clusData = []
                for traPath in describes2imgPathes[key]:
                    traDim = os.path.join(os.path.join(dataPath, studyI), traPath)
                    TraMapSagPoints = TraMapSag(sagPoints,traDim)
                    imgTRA = dicom2array(traDim)
                    # plt.subplot(2,int(len(value)/2)+1,index+1)
                    # plt.imshow(imgTRA)
                    plt.plot((TraMapSagPoints[0][0], TraMapSagPoints[1][0]), (TraMapSagPoints[0][1], TraMapSagPoints[1][1]))

                    x1,x2 = int(TraMapSagPoints[0][0]),int(TraMapSagPoints[1][0])
                    y1,y2 = int(TraMapSagPoints[0][1]),int(TraMapSagPoints[1][1])

                    clusData.append([y1,y2,x1,x2, traDim])
                    plt.plot(x1, y1, "o", color='red', ms=10)
                    plt.plot(x2, y2, "o", color='g', ms=10)
                    plt.plot(int((x1+x2)/2), int((y1+y2)/2), "o", color='g', ms=10)
                    plt.text(x1, y1,str(index))
                    index += 1


                thresh = 30
                print(sorted(clusData,key=lambda x:x[0]))
                clusData = sorted(clusData, key=lambda x: x[0])
                clusDataN = [[i[0]] for i in clusData]
                traDimN = [i[-1] for i in clusData]
                clusters = hcluster.fclusterdata(np.array(clusDataN), thresh, criterion="distance")
                print(clusters,set(clusters.tolist()))

                clustersDic = dealCluster(clusters,clusData)
                print(clustersDic)
                d = sortPoint(d)
                for index, target in enumerate(d):
                    x, y, vd, c, p = target.split(',')
                    if vd == "disc":
                        print("==")
                        flag,dicm = xyIndcm(int(x),int(y),clustersDic)
                        if flag:
                            print(dicm)
                            plt.plot(int(x), int(y), "o", color='r', ms=5)
                plt.show()
    print(count)