目标:通过交互式方法,获取不规则区域。
原理:绘制上下两个不规则半圆,构成一个封闭式的不规则半圆,进而获取不规则区域。
用法:首先随机绘制一个上半圆,按下tab键,再绘制一个下半圆,再按tab键,就能获取不规则区域。
1. 框架
2. GetIrregularRoiArea
#-*- codeing = utf-8 -*-
#@Function: 分两个下划线进行一定区间的断层截取
#@Time : 2022/7/8 11:15
#@Author : yx
#@File : getIrregularRoiArea.py
#@Software : PyCharm
import cv2
import numpy as np
import os
import natsort
import pandas as pd
def imageBaseInformation(readPath):
readName = natsort.natsorted(os.listdir(readPath))
image = cv2.imread(os.path.join(readPath, readName[0]))
col = image.shape[1]
imageNum = len(readName)
return col, imageNum
'''parameter setting
Global variable'''
_WindowName = 'image_show' # show window name
filename_path = r'./Ori_img'
writefile_path = r'./line'
writeTest = r'./image'
widthValue, number = imageBaseInformation(filename_path)
print(number)
'initialization'
_ListColsValue = [0 for i in range(widthValue)]
_ListFollowPrevious = [0 for j in range(widthValue)]
_Flag = [0 for i1 in range(1)]
ktmp = [0 for i1 in range(1)]
_DictLen = range(1, number + 1)
print(_DictLen)
_DictAbove = dict.fromkeys(_DictLen, _ListColsValue)
_DictBelow = dict.fromkeys(_DictLen, _ListColsValue)
leftPoint, rightPoint = [0], [widthValue - 1]
''' Read sequential picture'''
def _imageRead(Filename_Path,Num):
filename_path = Filename_Path
finally_path = os.path.join(filename_path, Num) # splice file path
# finally_path = os.path.join(filename_path, str(Num)) # splice file path
input_image = cv2.imread(finally_path) # read the image
# if input_image.shape[2] == 3:
# input_image = cv2.imread(finally_path, cv2.IMREAD_GRAYSCALE)
return input_image
''' Use the mouse to draw dividing lines'''
def _drawSegmentationLine(Event,X,Y,Flags,Param):
if ktmp[0] % 2 == 1:
for i in range(leftPoint[0], rightPoint[0] + 1):
cv2.circle(_InputImage, (i, _ListFollowPrevious[i]), 0, (0, 255, 255), 0)
if Flags == cv2.EVENT_FLAG_LBUTTON: # The left mouse button is pressed to start drawing,(continue)
x_site,y_site = X,Y # The mouse position
if x_site >=0 and x_site < widthValue: # cols,
_ListColsValue[x_site] = y_site
cv2.circle(_InputImage,(x_site,y_site),0,(0,255,0),0) # draw a scatter , color is green
if Flags == cv2.EVENT_RBUTTONDOWN: # The right mouse button is pressed to draw a segmentation line
_nonzeroFind()
_coordinateRepair()
for i in range(widthValue):
cv2.circle(_InputImage,(i,_ListColsValue[i]),0,(0,0,255),0) ## draw a scatter , color is Red
if Event == cv2.EVENT_MBUTTONDOWN:
count = _ListColsValue.count(0)
if count != widthValue:
print('waring,Line drawing error')
for i in range(widthValue):
cv2.circle(_InputImage,(i,_ListFollowPrevious[i]),0,(0,0,255),0) ## draw a scatter , color is Red
_Flag[0] = 1
print('执行了中键')
''' segmentation Frame'''
def _segmentationFrame():
cv2.namedWindow(_WindowName)
cv2.setMouseCallback(_WindowName,_drawSegmentationLine)
" 发现非O值的位置"
def _nonzeroFind():
for i in range(widthValue):
if _ListColsValue[i] != 0:
leftPoint[0] = i
break
for i in range(widthValue):
if _ListColsValue[widthValue - i - 1] != 0:
rightPoint[0] = widthValue - i - 1
break
def _switchingMode(_InputImage):
for i in range(leftPoint[0], rightPoint[0] + 1):
cv2.circle(_InputImage, (i, _ListFollowPrevious[i]), 0, (0, 0, 255), 0)
''' index is 0,Coordinate repair,
The position does not change following the previous frame'''
def _coordinateRepair():
for i in range(leftPoint[0], rightPoint[0] + 1):
if _ListColsValue[i] == 0: # Take the same thing to the right
for j in range(i + 1, rightPoint[0] + 1):
if _ListColsValue[j] != 0:
_ListColsValue[i] = _ListColsValue[j]
break
if _ListColsValue[rightPoint[0] ] == 0: # Take the same thing to the left
for j in range(rightPoint[0] - 2, -1, -1):
if _ListColsValue[j] != 0:
_ListColsValue[rightPoint[0] - 1] = _ListColsValue[j]
break
''' put the segmentation information into the file.txt'''
def _recordData(File_Path,Layer):
def _clearTXT(File_Path): # clear txt content
file_path = File_Path
file = open(file_path,'wb')
file.close()
def _dataSave(File_Path,Data): # Record in txt
file_path = File_Path
data = Data
file = open(file_path,'a')
for i in range(len(data)):
data_value = str(data[i])
file.write(data_value)
file.write('\n')
file.close()
file_path = File_Path
layer = Layer
_clearTXT(file_path)
for i in range(1, number + 1):
if layer == 'above':
_dataSave(file_path,_DictAbove[i])
elif layer == 'below':
_dataSave(file_path,_DictBelow[i])
'''blood flow image generate'''
def _bloodFlowImage(Read_Path,Write_Path):
def _nonzero(lineList):
leftValue, rightValue = 0, 0
widthValue = len(lineList)
for i in range(widthValue):
if lineList[i] != 0:
leftValue = i
break
for i in range(widthValue):
if lineList[widthValue - i - 1] != 0:
rightValue = widthValue - i - 1
break
return leftValue, rightValue
write_path = Write_Path
read_path = Read_Path
list_output_image = [[0 for j in range(widthValue)] for i in range(number)]
matrix_output_image = np.array(list_output_image,dtype='uint8')
num = 1
nameImage = natsort.natsorted(os.listdir(read_path))
while(num < number + 1):
imagePath = nameImage[num - 1]
image_blood = _imageRead(read_path,imagePath)
image_blood = cv2.cvtColor(image_blood, cv2.COLOR_BGR2GRAY)
image_blood_matrix = np.array(image_blood)
rows = image_blood_matrix.shape[0]
cols = image_blood_matrix.shape[1]
left1, right1 = _nonzero(_DictAbove[num])
left2, right2 = _nonzero(_DictBelow[num])
for j in range(max(left1, left2), min(right1, right2) + 1):
value1, value2 = _DictAbove[num][j], _DictBelow[num][j]
if value1 < value2:
for i in range(value1, value2 + 1):
image_blood_matrix[i, j] = 0
else:
for i in range(value2, value1 + 1):
image_blood_matrix[i, j] = 0
# 获得封闭区域内的信息
Ori_image_blood = np.array(image_blood)
Circle_image_blood_matrix = Ori_image_blood - image_blood_matrix
writeTest1 = os.path.join(writeTest, str(num) + '.jpg')
cv2.imwrite(writeTest1, Circle_image_blood_matrix)
cv2.imwrite('./image/2.png', image_blood_matrix)
num += 1
''' Read file.txt ,alternative use'''
def _readFileTxt(Read_Path_Above,Read_Path_Below):
def _loadDataInt(infile):
file = open(infile, 'r')
sourceInLine = file.readlines()
dict_len = range(1, number + 1)
dict_return = dict.fromkeys(dict_len, _ListColsValue)
data_record = []
index_count = 0
for line in sourceInLine:
index_count += 1
temp1 = line.strip('\n')
data_record.append(int(temp1))
if index_count % widthValue == 0:
index_integer = index_count // widthValue
dict_return[index_integer] = data_record
data_record = []
return dict_return
read_path_above = Read_Path_Above
read_path_below = Read_Path_Below
above_dict = _loadDataInt(read_path_above)
below_dict = _loadDataInt(read_path_below)
return above_dict,below_dict
if __name__=='__main__':
''' Initialize the relevant data'''
# The path to store the data
''' above,segmentation main procedure'''
num = 1
nameImage = natsort.natsorted(os.listdir(filename_path))
while (num <= number):
# print('segmentation frame is ',num)
_Flag[0] = 0
_InputImage = _imageRead(filename_path,nameImage[num - 1])
_segmentationFrame()
_ListColsValue = [0 for i in range(widthValue)]
while (1):
cv2.imshow(_WindowName, _InputImage)
interactive_value = cv2.waitKey(1) & 0xFF
if interactive_value == 9:
if ktmp[0] % 2 == 0:
print('segmentation frame is ', num, 'above line')
_nonzeroFind()
_coordinateRepair()
_DictAbove[num] = _ListColsValue
_ListFollowPrevious = _ListColsValue
ktmp[0] = 1
else:
print('segmentation frame is ', num, 'below line')
_nonzeroFind()
_coordinateRepair()
_DictBelow[num] = _ListColsValue
ktmp[0] = 0
state_value = 'normal'
break
if interactive_value == 27:
state_value = 'again'
break
if state_value == 'normal':
if _Flag[0] == 0:
_ListFollowPrevious = _ListColsValue
if ktmp[0] % 2 != 1:
num += 1
save_above_filename_path = os.path.join(writefile_path, 'VRI_above.txt')
layer = 'above'
_recordData(save_above_filename_path,layer)
save_below_filename_path1 = os.path.join(writefile_path, 'VRI_below.txt')
layer = 'below'
_recordData(save_below_filename_path1, layer)
read_file_path = filename_path
_bloodFlowImage(read_file_path, writeTest)
# 计算封闭区域的面积 VAD
Datapoint_Above = pd.read_csv('./line/VRI_above.txt')
Datapoint_Blow = pd.read_csv('./line/VRI_below.txt')
Datapoint_Above = np.array(Datapoint_Above)
Datapoint_Blow = np.array(Datapoint_Blow)
zero_lhz = np.zeros((600, 600),dtype='uint8')
for i in range(3,599):
upper = Datapoint_Above[i][0]
blow = Datapoint_Blow[i-2][0]
if upper != 0:
for j in range(upper, blow):
zero_lhz[j][i] = 255
cv2.imwrite('./image/mask.jpg', zero_lhz)
print('procedure end')