Compare commits
No commits in common. "master" and "main" have entirely different histories.
|
|
@ -3,4 +3,3 @@
|
|||
/workspace.xml
|
||||
# 基于编辑器的 HTTP 客户端请求
|
||||
/httpRequests/
|
||||
/vcs.xml
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
<module type="PYTHON_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="jdk" jdkName="spacetySliceEnv" jdkType="Python SDK" />
|
||||
<orderEntry type="jdk" jdkName="Python 3.9" jdkType="Python SDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
<component name="PyDocumentationSettings">
|
||||
|
|
|
|||
|
|
@ -3,5 +3,5 @@
|
|||
<component name="Black">
|
||||
<option name="sdkName" value="spacetySliceEnv" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="spacetySliceEnv" project-jdk-type="Python SDK" />
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.9" project-jdk-type="Python SDK" />
|
||||
</project>
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
|
|
@ -1,561 +0,0 @@
|
|||
import os
|
||||
import argparse
|
||||
from osgeo import ogr,gdal
|
||||
from matplotlib import pyplot as plt
|
||||
from osgeo import gdal
|
||||
import matplotlib
|
||||
import matplotlib.patches as patches
|
||||
from osgeo import gdal
|
||||
from PIL import Image
|
||||
from scipy.spatial import cKDTree
|
||||
import numpy as np
|
||||
from tools.DotaOperator import DotaObj,createDota,readDotaFile,writerDotaFile
|
||||
import argparse
|
||||
import math
|
||||
from math import ceil, floor
|
||||
|
||||
##########################################################################
|
||||
# 参数区
|
||||
##########################################################################
|
||||
SliceSize=5000
|
||||
|
||||
##########################################################################
|
||||
# 函数区
|
||||
##########################################################################
|
||||
def read_tif(path):
|
||||
dataset = gdal.Open(path) # 打开TIF文件
|
||||
if dataset is None:
|
||||
print("无法打开文件")
|
||||
return None, None, None
|
||||
|
||||
cols = dataset.RasterXSize # 图像宽度
|
||||
rows = dataset.RasterYSize # 图像高度
|
||||
bands = dataset.RasterCount
|
||||
im_proj = dataset.GetProjection() # 获取投影信息
|
||||
im_Geotrans = dataset.GetGeoTransform() # 获取仿射变换信息
|
||||
im_data = dataset.ReadAsArray(0, 0, cols, rows) # 读取栅格数据为NumPy数组
|
||||
print("行数:", rows)
|
||||
print("列数:", cols)
|
||||
print("波段:", bands)
|
||||
del dataset # 关闭数据集
|
||||
return im_proj, im_Geotrans, im_data
|
||||
|
||||
|
||||
def Strech_SquareRoot(im_data):
|
||||
# 判断是否为dB
|
||||
# immask = np.isfinite(im_data)
|
||||
# imvail_data = im_data[immask]
|
||||
# minvalue = np.percentile(imvail_data,30)
|
||||
# if minvalue<0 :
|
||||
# im_data=np.power(10.0,im_data/10.0)
|
||||
|
||||
im_data=np.sqrt(im_data)
|
||||
immask = np.isfinite(im_data)
|
||||
imvail_data = im_data[immask]
|
||||
|
||||
minvalue=np.nanmin(imvail_data)
|
||||
maxvalue=np.nanmax(imvail_data)
|
||||
minvalue_01Prec = np.percentile(imvail_data, 0.1) # 20250904 1%拉伸
|
||||
maxvalue_999Prec = np.percentile(imvail_data, 99.9)
|
||||
print('sqrt root min - max ', minvalue,maxvalue)
|
||||
if (maxvalue-minvalue)/(maxvalue_999Prec-minvalue_01Prec)>3: # 表示 拉伸之后,像素值绝大部分很有可能集中在 80
|
||||
minvalue=minvalue_01Prec
|
||||
maxvalue=maxvalue_999Prec
|
||||
print('sqrt root min(0.1) - max(99.9) ', minvalue, maxvalue)
|
||||
|
||||
|
||||
im_data = (im_data - minvalue) / (maxvalue - minvalue) * 254 + 1
|
||||
im_data = np.clip(im_data, 0, 255)
|
||||
|
||||
return im_data.astype(np.uint8)
|
||||
|
||||
def write_envi(im_data, im_geotrans, im_proj, output_path):
|
||||
"""
|
||||
将数组数据写入ENVI格式文件
|
||||
:param im_data: 输入的numpy数组(2D或3D)
|
||||
:param im_geotrans: 仿射变换参数(6元组)
|
||||
:param im_proj: 投影信息(WKT字符串)
|
||||
:param output_path: 输出文件路径(无需扩展名,会自动生成.dat和.hdr)
|
||||
"""
|
||||
im_bands = 1
|
||||
im_height, im_width = im_data.shape
|
||||
# 创建ENVI格式驱动
|
||||
driver = gdal.GetDriverByName("GTiff")
|
||||
dataset = driver.Create(output_path, im_width, im_height, 1, gdal.GDT_Float32)
|
||||
|
||||
if dataset is not None:
|
||||
dataset.SetGeoTransform(im_geotrans) # 设置地理变换参数
|
||||
dataset.SetProjection(im_proj) # 设置投影
|
||||
|
||||
dataset.GetRasterBand(1).WriteArray(im_data)
|
||||
|
||||
dataset.FlushCache() # 确保数据写入磁盘
|
||||
dataset = None # 关闭文件
|
||||
outfilepath=output_path.replace(".tiff",".png")
|
||||
im_data_uint8=Strech_SquareRoot(im_data)
|
||||
Image.fromarray(im_data_uint8).save(outfilepath, compress_level=0)
|
||||
|
||||
def geoXY2pixelXY(geo_x, geo_y, inv_gt):
|
||||
pixel_x = inv_gt[0] + geo_x * inv_gt[1] + geo_y * inv_gt[2]
|
||||
pixel_y = inv_gt[3] + geo_x * inv_gt[4] + geo_y * inv_gt[5]
|
||||
return pixel_x, pixel_y
|
||||
|
||||
def label2pixelpoints(dotapath,tiff_inv_trans,methodstr,filterlabels):
|
||||
dotalist = readDotaFile(dotapath,filterlabels)
|
||||
if methodstr=="geolabel":
|
||||
for i in range(len(dotalist)):
|
||||
geo_x = dotalist[i].x1 # x1
|
||||
geo_y = dotalist[i].y1
|
||||
pixel_x, pixel_y = geoXY2pixelXY(geo_x, geo_y, tiff_inv_trans)
|
||||
dotalist[i].x1 = pixel_x
|
||||
dotalist[i].y1 = pixel_y
|
||||
|
||||
geo_x = dotalist[i].x2 # x2
|
||||
geo_y = dotalist[i].y2
|
||||
pixel_x, pixel_y = geoXY2pixelXY(geo_x, geo_y, tiff_inv_trans)
|
||||
dotalist[i].x2 = pixel_x
|
||||
dotalist[i].y2 = pixel_y
|
||||
|
||||
geo_x = dotalist[i].x3 # x3
|
||||
geo_y = dotalist[i].y3
|
||||
pixel_x, pixel_y = geoXY2pixelXY(geo_x, geo_y, tiff_inv_trans)
|
||||
dotalist[i].x3 = pixel_x
|
||||
dotalist[i].y3 = pixel_y
|
||||
|
||||
geo_x = dotalist[i].x4 # x4
|
||||
geo_y = dotalist[i].y4
|
||||
pixel_x, pixel_y = geoXY2pixelXY(geo_x, geo_y, tiff_inv_trans)
|
||||
dotalist[i].x4 = pixel_x
|
||||
dotalist[i].y4 = pixel_y
|
||||
|
||||
print("点数:", len(dotalist))
|
||||
return dotalist
|
||||
|
||||
def getMaxEdge(dotalist, ids):
|
||||
cornpoint = np.zeros((len(ids) * 4, 2))
|
||||
for idx in range(len(ids)):
|
||||
cornpoint[idx * 4 + 0, 0] = dotalist[ids[idx]].x1
|
||||
cornpoint[idx * 4 + 1, 0] = dotalist[ids[idx]].x2
|
||||
cornpoint[idx * 4 + 2, 0] = dotalist[ids[idx]].x3
|
||||
cornpoint[idx * 4 + 3, 0] = dotalist[ids[idx]].x4
|
||||
|
||||
cornpoint[idx * 4 + 0, 1] = dotalist[ids[idx]].y1
|
||||
cornpoint[idx * 4 + 1, 1] = dotalist[ids[idx]].y2
|
||||
cornpoint[idx * 4 + 2, 1] = dotalist[ids[idx]].y3
|
||||
cornpoint[idx * 4 + 3, 1] = dotalist[ids[idx]].y4
|
||||
|
||||
xedge = np.max(cornpoint[:, 0]) - np.min(cornpoint[:, 0])
|
||||
yedge = np.max(cornpoint[:, 1]) - np.min(cornpoint[:, 1])
|
||||
|
||||
edgelen = xedge if xedge > yedge else yedge
|
||||
return edgelen
|
||||
|
||||
def getExternCenter(dotalist, ids):
|
||||
cornpoint = np.zeros((len(ids) * 4, 2))
|
||||
for idx in range(len(ids)):
|
||||
cornpoint[idx * 4 + 0, 0] = dotalist[ids[idx]].x1
|
||||
cornpoint[idx * 4 + 1, 0] = dotalist[ids[idx]].x2
|
||||
cornpoint[idx * 4 + 2, 0] = dotalist[ids[idx]].x3
|
||||
cornpoint[idx * 4 + 3, 0] = dotalist[ids[idx]].x4
|
||||
|
||||
cornpoint[idx * 4 + 0, 1] = dotalist[ids[idx]].y1
|
||||
cornpoint[idx * 4 + 1, 1] = dotalist[ids[idx]].y2
|
||||
cornpoint[idx * 4 + 2, 1] = dotalist[ids[idx]].y3
|
||||
cornpoint[idx * 4 + 3, 1] = dotalist[ids[idx]].y4
|
||||
|
||||
minX = np.min(cornpoint[:, 0])
|
||||
minY = np.min(cornpoint[:, 1])
|
||||
maxX = np.max(cornpoint[:, 0])
|
||||
maxY = np.max(cornpoint[:, 1])
|
||||
centerX = (minX + maxX) / 2
|
||||
centerY = (minY + maxY) / 2
|
||||
return [centerX, centerY, minX, minY, maxX, maxY]
|
||||
|
||||
def drawSliceRasterPrivew(tiff_data,dotalist,clusterDict):
|
||||
# 绘制图形
|
||||
# 创建图形和坐标轴
|
||||
fig, ax = plt.subplots(figsize=(20, 16))
|
||||
ax.imshow(tiff_data, cmap='gray')
|
||||
# 绘制每个目标的矩形框并标注坐标
|
||||
for i in range(len(dotalist)):
|
||||
# 提取x和y坐标
|
||||
x_coords = [dotalist[i].x1, dotalist[i].x2, dotalist[i].x3, dotalist[i].x4]
|
||||
y_coords = [dotalist[i].y1, dotalist[i].y2, dotalist[i].y3, dotalist[i].y4]
|
||||
|
||||
# 计算最小外接矩形(AABB)
|
||||
x_min, x_max = min(x_coords), max(x_coords)
|
||||
y_min, y_max = min(y_coords), max(y_coords)
|
||||
width = x_max - x_min
|
||||
height = y_max - y_min
|
||||
|
||||
# 绘制无填充矩形框(仅红色边框)
|
||||
rect = patches.Rectangle(
|
||||
(x_min, y_min), width, height,
|
||||
linewidth=2, edgecolor='red', facecolor='none' # 关键:facecolor='none'
|
||||
)
|
||||
ax.add_patch(rect)
|
||||
|
||||
# ax.annotate(f'({x},{y})', xy=(x, y), xytext=(5, 5),
|
||||
# textcoords='offset points', fontsize=10,
|
||||
# bbox=dict(boxstyle='round,pad=0.5', fc='white', alpha=0.8))
|
||||
|
||||
# 在矩形中心标注目标编号
|
||||
center_x = sum(x_coords) / 4
|
||||
center_y = sum(y_coords) / 4
|
||||
ax.text(center_x, center_y, str(i),
|
||||
ha='center', va='center', fontsize=6, color='red')
|
||||
|
||||
# 以类别中心为中心绘制四边形
|
||||
for k in clusterDict:
|
||||
# 绘制无填充矩形框(仅红色边框)
|
||||
minX = clusterDict[k]["p"][0]
|
||||
minY = clusterDict[k]["p"][1]
|
||||
rect = patches.Rectangle(
|
||||
(minX , minY), SliceSize, SliceSize,
|
||||
linewidth=2, edgecolor='green', facecolor='none' # 关键:facecolor='none'
|
||||
)
|
||||
ax.add_patch(rect)
|
||||
ax.text(minX+512, minY+512, str(k),
|
||||
ha='center', va='center', fontsize=6, color='green')
|
||||
|
||||
plt.tight_layout()
|
||||
plt.show()
|
||||
|
||||
print("绘图结束")
|
||||
return None
|
||||
|
||||
def find_optimal_slices(H, W, boxes, patch_size=1024, max_overlap_rate=0.2):
|
||||
"""
|
||||
Compute optimal slice positions for the image to maximize the number of fully contained rectangular patches (boxes),
|
||||
while ensuring the overlap rate between any two slices does not exceed the specified maximum.
|
||||
|
||||
Parameters:
|
||||
- H: Height of the image.
|
||||
- W: Width of the image.
|
||||
- boxes: List of tuples or lists, each containing (x1, y1, x2, y2) where (x1, y1) is the top-left and (x2, y2) is the bottom-right of a rectangular patch.
|
||||
- patch_size: Size of each slice (square, e.g., 1024).
|
||||
- max_overlap_rate: Maximum allowed overlap rate (e.g., 0.2).
|
||||
|
||||
Returns:
|
||||
- slices: List of (sx, sy) starting positions for the slices.
|
||||
- covered_count: Number of patches that appear fully in at least one slice.
|
||||
"""
|
||||
overlap_max = patch_size * max_overlap_rate
|
||||
stride = patch_size - floor(overlap_max) # Ensures overlap <= max_overlap_rate in linear dimensions
|
||||
|
||||
N = len(boxes)
|
||||
x_covered = [set() for _ in range(stride)]
|
||||
y_covered = [set() for _ in range(stride)]
|
||||
|
||||
for i in range(N):
|
||||
x1, y1, x2, y2 = boxes[i]
|
||||
b_w = x2 - x1
|
||||
b_h = y2 - y1
|
||||
|
||||
# For x-dimension
|
||||
lx = max(0, x2 - patch_size)
|
||||
rx = min(W - patch_size, x1)
|
||||
if lx <= rx:
|
||||
start_x = ceil(lx)
|
||||
end_x = floor(rx)
|
||||
l_x = end_x - start_x + 1
|
||||
if l_x > 0:
|
||||
if l_x >= stride:
|
||||
for ox in range(stride):
|
||||
x_covered[ox].add(i)
|
||||
else:
|
||||
for sx in range(start_x, end_x + 1):
|
||||
ox = sx % stride
|
||||
x_covered[ox].add(i)
|
||||
|
||||
# For y-dimension
|
||||
ly = max(0, y2 - patch_size)
|
||||
ry = min(H - patch_size, y1)
|
||||
if ly <= ry:
|
||||
start_y = ceil(ly)
|
||||
end_y = floor(ry)
|
||||
l_y = end_y - start_y + 1
|
||||
if l_y > 0:
|
||||
if l_y >= stride:
|
||||
for oy in range(stride):
|
||||
y_covered[oy].add(i)
|
||||
else:
|
||||
for sy in range(start_y, end_y + 1):
|
||||
oy = sy % stride
|
||||
y_covered[oy].add(i)
|
||||
|
||||
# Find the best offset pair (ox, oy) that maximizes covered patches
|
||||
max_covered = 0
|
||||
best_ox = 0
|
||||
best_oy = 0
|
||||
for ox in range(stride):
|
||||
for oy in range(stride):
|
||||
current_covered = len(x_covered[ox] & y_covered[oy])
|
||||
if current_covered > max_covered:
|
||||
max_covered = current_covered
|
||||
best_ox = ox
|
||||
best_oy = oy
|
||||
|
||||
# Generate the slice positions using the best offsets and stride
|
||||
slices = []
|
||||
sx = best_ox
|
||||
while sx + patch_size <= W:
|
||||
sy = best_oy
|
||||
while sy + patch_size <= H:
|
||||
slices.append((sx, sy))
|
||||
sy += stride
|
||||
sx += stride
|
||||
|
||||
return slices, max_covered
|
||||
|
||||
def check_B_in_A(A,B):
|
||||
"""
|
||||
判断A包含B
|
||||
:param A: [x0,y0.w.h]
|
||||
:param B: [x0,y0.w.h]
|
||||
:return:
|
||||
"""
|
||||
# 解构矩形A和B的参数
|
||||
Ax0, Ay0, Aw, Ah = A
|
||||
Bx0, By0, Bw, Bh = B
|
||||
|
||||
# 计算矩形A和B的右边界和下边界
|
||||
Ax1 = Ax0 + Aw
|
||||
Ay1 = Ay0 + Ah
|
||||
|
||||
Bx1 = Bx0 + Bw
|
||||
By1 = By0 + Bh
|
||||
|
||||
# 判断B是否完全在A内部
|
||||
return (Bx0 >= Ax0) and (Bx1 <= Ax1) and (By0 >= Ay0) and (By1 <= Ay1)
|
||||
|
||||
|
||||
##########################################################################
|
||||
# 切分算法流程图
|
||||
##########################################################################
|
||||
|
||||
def getclusterDict(dotalist,imgheight,imgwidth,pitchSize=1024,max_overlap_rate=0.2):
|
||||
"""
|
||||
生成切片数据
|
||||
:param dotalist: 样本集
|
||||
:param imgheight: 图像高度
|
||||
:param imgwidth: 图像宽度
|
||||
:return: 切片类型
|
||||
"""
|
||||
boxs=[]
|
||||
for i in range(len(dotalist)):
|
||||
xs=np.array([dotalist[i].x1,dotalist[i].x2,dotalist[i].x3, dotalist[i].x4])
|
||||
ys=np.array([dotalist[i].y1,dotalist[i].y2,dotalist[i].y3, dotalist[i].y4])
|
||||
x1=np.min(xs)
|
||||
x2=np.max(xs)
|
||||
y1=np.min(ys)
|
||||
y2=np.max(ys)
|
||||
boxs.append([x1,y1,x2,y2]) # x1, y1, x2, y2 = boxes[i]
|
||||
|
||||
slices, max_covered=find_optimal_slices(imgheight,imgwidth,boxs,pitchSize,max_overlap_rate)
|
||||
|
||||
clusterDict={}
|
||||
|
||||
waitContaindota=[]
|
||||
hasContainIds=[]
|
||||
for i in range(len(slices)):
|
||||
sx,sy=slices[i]
|
||||
clusterDict[i]={"p":[sx,sy],"id":[]}
|
||||
slicesExten=[sx,sy,SliceSize,SliceSize]
|
||||
for ids in range(len(dotalist)):
|
||||
if ids in hasContainIds:
|
||||
continue
|
||||
else:
|
||||
[centerX, centerY, minX, minY, maxX, maxY]=getExternCenter(dotalist, [ids])
|
||||
dotaExtend=[minX,minY,maxX-minX,maxY-minY]
|
||||
if check_B_in_A(slicesExten,dotaExtend):
|
||||
print("True: ", slicesExten, dotaExtend)
|
||||
clusterDict[i]["id"].append(ids)
|
||||
# hasContainIds.append(ids)
|
||||
else:
|
||||
print("False: ",slicesExten,dotaExtend)
|
||||
|
||||
for ids in range(len(dotalist)):
|
||||
if ids in hasContainIds:
|
||||
continue
|
||||
else:
|
||||
waitContaindota.append(ids)
|
||||
print("No in slice dota : ",str(dotalist[ids]) )
|
||||
|
||||
print("no process ids ",str(waitContaindota))
|
||||
return clusterDict
|
||||
|
||||
|
||||
def drawSlictplot(clusterDict,dotalist,tiff_data,nrows=10,ncols=9):
|
||||
"""
|
||||
:param clusterDict: clusterDict[i]={"p":[sx,sy],"id":[]}
|
||||
:param dotalist: (x1, y1, x2, y2, x3, y3, x4, y4 clsname diffcule)
|
||||
:return:
|
||||
"""
|
||||
fig, axes = plt.subplots(nrows=nrows,ncols=ncols,figsize=(20, 16))
|
||||
plt.tight_layout(pad=3.0)
|
||||
print(tiff_data.shape)
|
||||
# 9*10
|
||||
subid=0
|
||||
for cid in clusterDict:
|
||||
sx,sy=clusterDict[cid]["p"]
|
||||
colid=subid//nrows
|
||||
rowid=subid%nrows
|
||||
subid=subid+1
|
||||
ax = axes[rowid]
|
||||
ax.set_title(str(cid))
|
||||
sliceData=tiff_data[sy:(sy+SliceSize),sx:(sx+SliceSize)]
|
||||
ax.imshow(sliceData, cmap='gray')
|
||||
|
||||
for did in clusterDict[cid]["id"] :
|
||||
# 提取x和y坐标
|
||||
x_coords = [dotalist[did].x1-sx, dotalist[did].x2-sx, dotalist[did].x3-sx, dotalist[did].x4-sx]
|
||||
y_coords = [dotalist[did].y1-sy, dotalist[did].y2-sy, dotalist[did].y3-sy, dotalist[did].y4-sy]
|
||||
|
||||
# 计算最小外接矩形(AABB)
|
||||
x_min, x_max = min(x_coords), max(x_coords)
|
||||
y_min, y_max = min(y_coords), max(y_coords)
|
||||
width = x_max - x_min
|
||||
height = y_max - y_min
|
||||
|
||||
|
||||
# 绘制无填充矩形框(仅红色边框)
|
||||
rect = patches.Rectangle(
|
||||
(x_min, y_min), width, height,
|
||||
linewidth=2, edgecolor='red', facecolor='none' # 关键:facecolor='none'
|
||||
)
|
||||
ax.add_patch(rect)
|
||||
|
||||
# 在矩形中心标注目标编号
|
||||
center_x = x_min+width/2
|
||||
center_y = y_min+height/2
|
||||
ax.text(center_x, center_y, str(did),
|
||||
ha='center', va='center', fontsize=6, color='red')
|
||||
|
||||
|
||||
plt.tight_layout()
|
||||
plt.show()
|
||||
|
||||
print("绘图结束")
|
||||
return None
|
||||
|
||||
|
||||
def slictDataAndOutlabel(clusterDict,dotalist,tiff_data,tiff_basename,outfolderpath,im_geotrans, im_proj):
|
||||
"""
|
||||
切分标签,输出结果与文件
|
||||
:param clusterDict:
|
||||
:param dotalist:
|
||||
:param tiff_data:
|
||||
:param tiff_name:
|
||||
:param outfolderpath:
|
||||
:return:
|
||||
"""
|
||||
for cid in clusterDict:
|
||||
sx, sy = clusterDict[cid]["p"]
|
||||
if len(clusterDict[cid]["id"])==0:
|
||||
continue
|
||||
sliceData = tiff_data[sy:(sy + SliceSize), sx:(sx + SliceSize)]
|
||||
outbinname="{}_{}.tiff".format(tiff_basename,cid)
|
||||
outlabelname="{}_{}.txt".format(tiff_basename,cid)
|
||||
# 获取样本列表
|
||||
outdotalist=[]
|
||||
for did in clusterDict[cid]["id"] :
|
||||
x1=dotalist[did].x1-sx
|
||||
x2=dotalist[did].x2-sx
|
||||
x3=dotalist[did].x3-sx
|
||||
x4=dotalist[did].x4-sx
|
||||
y1=dotalist[did].y1-sy
|
||||
y2=dotalist[did].y2-sy
|
||||
y3=dotalist[did].y3-sy
|
||||
y4=dotalist[did].y4-sy
|
||||
tempdota=createDota(x1,y1,x2,y2,x3,y3,x4,y4,dotalist[did].clsname,dotalist[did].difficulty)
|
||||
outdotalist.append(tempdota)
|
||||
|
||||
outlabelpath=os.path.join(outfolderpath,outlabelname)
|
||||
outbinpath=os.path.join(outfolderpath,outbinname)
|
||||
|
||||
temp_im_geotrans=[tempi for tempi in im_geotrans]
|
||||
# 处理 0,3
|
||||
temp_im_geotrans[0]=im_geotrans[0]+sx*im_geotrans[1]+im_geotrans[2]*sy # x
|
||||
temp_im_geotrans[3]=im_geotrans[3]+sx*im_geotrans[4]+im_geotrans[5]*sy # y
|
||||
write_envi(sliceData,temp_im_geotrans,im_proj,outbinpath)
|
||||
writerDotaFile(outdotalist,outlabelpath)
|
||||
|
||||
##########################################################################
|
||||
# 处理流程图
|
||||
##########################################################################
|
||||
def DataSampleSliceRasterProcess(inbinfile,labelfilepath,outfolderpath,methodstr,filterlabels):
|
||||
tiff_proj, tiff_trans, tiff_data = read_tif(inbinfile)
|
||||
tiff_inv_trans = gdal.InvGeoTransform(tiff_trans)
|
||||
dotalist=label2pixelpoints(labelfilepath,tiff_inv_trans,methodstr,filterlabels)
|
||||
imgheight, imgwidth=tiff_data.shape
|
||||
clusterDict=getclusterDict(dotalist,imgheight,imgwidth,SliceSize,0.25)
|
||||
# drawSliceRasterPrivew(tiff_data, dotalist, clusterDict)
|
||||
nrows=int(len(clusterDict)/1+1)
|
||||
# drawSlictplot(clusterDict, dotalist, tiff_data, nrows, 1)
|
||||
tiff_name=os.path.basename(inbinfile)
|
||||
tiff_basename=os.path.splitext(tiff_name)[0]
|
||||
slictDataAndOutlabel(clusterDict, dotalist, tiff_data, tiff_basename, outfolderpath, tiff_trans, tiff_proj)
|
||||
|
||||
pass
|
||||
|
||||
|
||||
|
||||
def getParams():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('-i','--inbinfile',type=str,default=r'D:\港口\Geo_bc2-sm-org-vv-20231016t135315-008424-0020e8-01.tiff', help='输入tiff的bin文件')
|
||||
parser.add_argument('-l', '--labelfilepath',type=str,default=r"D:\港口\港口dota\Geo_bc2-sm-org-vv-20231016t135315-008424-0020e8-01.military_harbor.txt", help='输入标注')
|
||||
parser.add_argument('-o', '--outfolderpath',type=str,default=r'D:\港口\切片结果', help='切片文件夹地址')
|
||||
parser.add_argument('-f', '--filterlabel',type=str,default=r'mix_airport;civil_harbor;military_harbor;no_harbor', help='标签过滤')
|
||||
group = parser.add_mutually_exclusive_group()
|
||||
group.add_argument(
|
||||
'--geolabel',
|
||||
action='store_const',
|
||||
const='geolabel',
|
||||
dest='method',
|
||||
help='标注坐标点为地理坐标'
|
||||
)
|
||||
group.add_argument(
|
||||
'--pixellabel',
|
||||
action='store_const',
|
||||
const='pixellabel',
|
||||
dest='method',
|
||||
help='标注坐标系统为输入影像的像空间坐标'
|
||||
)
|
||||
parser.set_defaults(method='geolabel')
|
||||
|
||||
|
||||
args = parser.parse_args()
|
||||
return args
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
parser = getParams()
|
||||
inbinfile=parser.inbinfile
|
||||
labelfilepath=parser.labelfilepath
|
||||
outfolderpath=parser.outfolderpath
|
||||
methodstr= parser.method
|
||||
filterlabels=parser.filterlabel.strip().split(';')
|
||||
print('inbinfile=',inbinfile)
|
||||
print('labelfilepath=',labelfilepath)
|
||||
print('outfolderpath=',outfolderpath)
|
||||
print('methodstr=',methodstr)
|
||||
print('filterlabels=',filterlabels)
|
||||
DataSampleSliceRasterProcess(inbinfile, labelfilepath, outfolderpath,methodstr,filterlabels)
|
||||
print("样本切分完成")
|
||||
exit(2)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
exit(3)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,135 +0,0 @@
|
|||
import numpy as np
|
||||
import os
|
||||
from glob import glob
|
||||
from pathlib import Path
|
||||
from multiprocessing import Pool
|
||||
########################################################
|
||||
# 函数区
|
||||
########################################################
|
||||
|
||||
spacetySliceEnvPathExEPath=r"d:\ProgramData\anaconda3\envs\spacetySliceEnv\python.exe"
|
||||
|
||||
def find_tif_files_pathlib(directory):
|
||||
"""
|
||||
使用pathlib.Path.rglob递归查找指定目录下所有.tif和.tiff文件
|
||||
|
||||
参数:
|
||||
directory (str): 要搜索的根目录路径
|
||||
|
||||
返回:
|
||||
list: 包含所有找到的.tif/.tiff文件完整路径的列表
|
||||
"""
|
||||
path = Path(directory)
|
||||
# 使用rglob递归匹配所有.tif和.tiff文件
|
||||
tif_files = list(path.rglob('*.tiff'))+list(path.rglob('*.tif'))
|
||||
# 将Path对象转换为字符串路径
|
||||
return [str(file) for file in tif_files]
|
||||
|
||||
|
||||
def find_txt_files_pathlib(directory):
|
||||
"""
|
||||
使用pathlib.Path.rglob递归查找指定目录下所有.tif和.tiff文件
|
||||
|
||||
参数:
|
||||
directory (str): 要搜索的根目录路径
|
||||
|
||||
返回:
|
||||
list: 包含所有找到的.tif/.tiff文件完整路径的列表
|
||||
"""
|
||||
path = Path(directory)
|
||||
# 使用rglob递归匹配所有.tif和.tiff文件
|
||||
tif_files = list(path.rglob('*.txt'))
|
||||
# 将Path对象转换为字符串路径
|
||||
return [str(file) for file in tif_files]
|
||||
|
||||
|
||||
def matchTiff_Txt(tiffpaths,txtPaths):
|
||||
match_results={}
|
||||
tiffID=0
|
||||
for tid in range(len(tiffpaths)):
|
||||
tiffID=tiffID+1
|
||||
match_results[tiffID]={"tiff":tiffpaths[tid],"txt":[]}
|
||||
rootname=Path(tiffpaths[tid]).stem
|
||||
for txtpath in txtPaths:
|
||||
txtrootname=Path(txtpath).stem
|
||||
if txtrootname.startswith(rootname):
|
||||
match_results[tiffID]["txt"].append(txtpath)
|
||||
|
||||
return match_results
|
||||
|
||||
def sliceTiFFAndTxt(match_meta,outfolderpath):
|
||||
resultTxt=""
|
||||
programpath = r"R:\TYSAR-德清院\A-预处理-未标注\A0-算法版本\AA\SpacetySliceDataTools\LabelPortShipRasterSlice\DataSamplePortSliceRaster_AA.py"
|
||||
tiffPath=match_meta["tiff"]
|
||||
for txtpath in match_meta["txt"]:
|
||||
cmdtxt = r"{} {} -i {} -l {} -o {}".format(spacetySliceEnvPathExEPath, programpath,
|
||||
tiffPath,
|
||||
txtpath,
|
||||
outfolderpath
|
||||
)
|
||||
|
||||
if os.system(cmdtxt) == 2:
|
||||
resultTxt="{}\nsucess: {}".format(resultTxt,txtpath)
|
||||
print("sucess:", cmdtxt)
|
||||
|
||||
else:
|
||||
resultTxt = "{}\nfailed: {}".format(resultTxt, txtpath)
|
||||
print("failed:", cmdtxt)
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
preFolderPath = r"R:\TYSAR-德清院\TYSAR-条带模式(SM)\港口\20250813-不分类\0-原图"
|
||||
dotafolderPath=r"D:\港口\港口dota"
|
||||
outfolderPath=r"D:\港口\切片结果"
|
||||
tiffPaths = find_tif_files_pathlib(preFolderPath)
|
||||
txtPaths = find_txt_files_pathlib(dotafolderPath)
|
||||
match_results=matchTiff_Txt(tiffPaths,txtPaths)
|
||||
|
||||
for tiffID in match_results:
|
||||
match_meta=match_results[tiffID]
|
||||
sliceTiFFAndTxt(match_meta,outfolderPath)
|
||||
|
||||
preFolderPath = r"R:\TYSAR-德清院\TYSAR-条带模式(SM)\港口\20250818-不分类\0-原图"
|
||||
dotafolderPath=r"D:\港口\港口dota"
|
||||
outfolderPath=r"D:\港口\切片结果"
|
||||
tiffPaths = find_tif_files_pathlib(preFolderPath)
|
||||
txtPaths = find_txt_files_pathlib(dotafolderPath)
|
||||
match_results=matchTiff_Txt(tiffPaths,txtPaths)
|
||||
|
||||
for tiffID in match_results:
|
||||
match_meta=match_results[tiffID]
|
||||
sliceTiFFAndTxt(match_meta,outfolderPath)
|
||||
|
||||
preFolderPath = r"R:\TYSAR-德清院\TYSAR-条带模式(SM)\港口\20250826-不分类\0-原图"
|
||||
dotafolderPath=r"D:\港口\港口dota"
|
||||
outfolderPath=r"D:\港口\切片结果"
|
||||
tiffPaths = find_tif_files_pathlib(preFolderPath)
|
||||
txtPaths = find_txt_files_pathlib(dotafolderPath)
|
||||
match_results=matchTiff_Txt(tiffPaths,txtPaths)
|
||||
|
||||
for tiffID in match_results:
|
||||
match_meta=match_results[tiffID]
|
||||
sliceTiFFAndTxt(match_meta,outfolderPath)
|
||||
|
||||
preFolderPath = r"R:\TYSAR-德清院\TYSAR-条带模式(SM)\港口\20250903-不分类\0-原图"
|
||||
dotafolderPath=r"D:\港口\港口dota"
|
||||
outfolderPath=r"D:\港口\切片结果"
|
||||
tiffPaths = find_tif_files_pathlib(preFolderPath)
|
||||
txtPaths = find_txt_files_pathlib(dotafolderPath)
|
||||
match_results=matchTiff_Txt(tiffPaths,txtPaths)
|
||||
|
||||
for tiffID in match_results:
|
||||
match_meta=match_results[tiffID]
|
||||
sliceTiFFAndTxt(match_meta,outfolderPath)
|
||||
|
||||
preFolderPath = r"R:\TYSAR-德清院\TYSAR-条带模式(SM)\港口\20250910-不分类\0-原图"
|
||||
dotafolderPath=r"D:\港口\港口dota"
|
||||
outfolderPath=r"D:\港口\切片结果"
|
||||
tiffPaths = find_tif_files_pathlib(preFolderPath)
|
||||
txtPaths = find_txt_files_pathlib(dotafolderPath)
|
||||
match_results=matchTiff_Txt(tiffPaths,txtPaths)
|
||||
|
||||
for tiffID in match_results:
|
||||
match_meta=match_results[tiffID]
|
||||
sliceTiFFAndTxt(match_meta,outfolderPath)
|
||||
|
|
@ -1,446 +0,0 @@
|
|||
from osgeo import ogr
|
||||
import os
|
||||
import argparse
|
||||
from osgeo import ogr
|
||||
import os
|
||||
import argparse
|
||||
from osgeo import ogr, gdal
|
||||
import os
|
||||
import argparse
|
||||
import numpy as np
|
||||
from scipy.spatial import KDTree
|
||||
from tools.DotaOperator import DotaObj,readDotaFile,writerDotaFile,createDota
|
||||
from glob import glob
|
||||
from pathlib import Path
|
||||
import shutil
|
||||
|
||||
|
||||
MLCName="MLC" # M
|
||||
JLCName="JLC" # J
|
||||
MJLCName="MJLC" # JM 混合
|
||||
NOLCName="NOLC" # 没有港口
|
||||
|
||||
|
||||
|
||||
def find_tif_files_pathlib(directory):
|
||||
path = Path(directory)
|
||||
# 使用rglob递归匹配所有.tif和.tiff文件
|
||||
tif_files = list(path.rglob('*.tiff'))+list(path.rglob('*.tif'))
|
||||
# 将Path对象转换为字符串路径
|
||||
return [str(file) for file in tif_files]
|
||||
|
||||
|
||||
def find_srcPath(srcFolder):
|
||||
root_path = Path(srcFolder)
|
||||
target_path = [folderpath for folderpath in root_path.rglob("*") if folderpath.is_dir() and folderpath.name=="0-原图"]
|
||||
tiff_files = []
|
||||
for folderpath in target_path:
|
||||
tiff_files=tiff_files+find_tif_files_pathlib(folderpath)
|
||||
|
||||
tiff_dict={}
|
||||
for filepath in tiff_files:
|
||||
rootname=Path(filepath).stem
|
||||
tiff_dict[rootname]=filepath
|
||||
|
||||
return tiff_dict
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def read_tifInfo(path):
|
||||
dataset = gdal.Open(path) # 打开TIF文件
|
||||
if dataset is None:
|
||||
print("无法打开文件,读取文件信息")
|
||||
return None, None, None
|
||||
|
||||
cols = dataset.RasterXSize # 图像宽度
|
||||
rows = dataset.RasterYSize # 图像高度
|
||||
bands = dataset.RasterCount
|
||||
im_proj = dataset.GetProjection() # 获取投影信息
|
||||
im_Geotrans = dataset.GetGeoTransform() # 获取仿射变换信息
|
||||
# im_data = dataset.ReadAsArray(0, 0, cols, rows) # 读取栅格数据为NumPy数组
|
||||
print("行数:", rows)
|
||||
print("列数:", cols)
|
||||
print("波段:", bands)
|
||||
x1=im_Geotrans[0]+im_Geotrans[1]*0
|
||||
x2=im_Geotrans[0]+im_Geotrans[1]*cols
|
||||
|
||||
y1=im_Geotrans[3]+im_Geotrans[5]*0
|
||||
y2=im_Geotrans[3]+im_Geotrans[5]*rows
|
||||
|
||||
xmin=min(x1,x2)
|
||||
xmax=max(x1,x2)
|
||||
ymin=min(y1,y2)
|
||||
ymax=max(y1,y2)
|
||||
|
||||
geoExtend=[xmin,ymin,xmax,ymax]
|
||||
del dataset # 关闭数据集
|
||||
return im_proj, im_Geotrans,geoExtend
|
||||
|
||||
def getshapefileInfo(shp_path):
|
||||
"""
|
||||
将Shapefile转换为DOTA格式
|
||||
:param shp_path: Shapefile文件路径
|
||||
"""
|
||||
|
||||
geom_points=[]
|
||||
|
||||
print("shapefile: ",shp_path)
|
||||
|
||||
# 注册所有驱动
|
||||
ogr.RegisterAll()
|
||||
|
||||
# 打开Shapefile文件
|
||||
driver = ogr.GetDriverByName('ESRI Shapefile')
|
||||
datasource = driver.Open(shp_path, 0)
|
||||
if datasource is None:
|
||||
print("无法打开Shapefile文件")
|
||||
return
|
||||
|
||||
print("layer count: ",datasource.GetLayerCount())
|
||||
for layerid in range(datasource.GetLayerCount()):
|
||||
print("layer id: ",layerid)
|
||||
# 获取图层
|
||||
layer = datasource.GetLayer(layerid)
|
||||
layer_defn=layer.GetLayerDefn()
|
||||
field_count=layer_defn.GetFieldCount()
|
||||
|
||||
print("field_count:", field_count)
|
||||
for i in range (field_count):
|
||||
field_defn=layer_defn.GetFieldDefn(i)
|
||||
field_name=field_defn.GetName()
|
||||
field_type=field_defn.GetType()
|
||||
field_type_name=field_defn.GetFieldTypeName(field_type)
|
||||
print("field_name:", field_name, field_type_name, field_type_name)
|
||||
|
||||
for feature in layer:
|
||||
geom = feature.GetGeometryRef()
|
||||
if geom.GetGeometryName() == 'POINT':
|
||||
x=geom.GetX()
|
||||
y=geom.GetY()
|
||||
geom_points.append([x,y])
|
||||
return np.array(geom_points)
|
||||
|
||||
|
||||
def getTiffsInfo(tiffnames,folderpath):
|
||||
"""
|
||||
获取所有影像的几何信息
|
||||
Args:
|
||||
tiff_paths: tiff列表
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
tiffdict={}
|
||||
for tiff_name in tiffnames:
|
||||
if tiff_name.endswith(".tiff"):
|
||||
tiff_path=os.path.join(folderpath,tiff_name)
|
||||
im_proj, im_Geotrans, geoExtend=read_tifInfo(tiff_path)
|
||||
tiffdict[tiff_name]={"geoExtend":geoExtend,"geoTrans":im_Geotrans,"imProj":im_proj}
|
||||
return tiffdict
|
||||
|
||||
|
||||
def getMJSignal(tiffpath,shipPortTree,outfolderPath):
|
||||
rootname=Path(tiffpath).stem
|
||||
portTxtpath=os.path.join(outfolderPath,rootname+".txt")
|
||||
im_proj, im_Geotrans, geoExtend = read_tifInfo(tiffpath) # geoExtend : [xmin,ymin,xmax,ymax]
|
||||
[xmin, ymin, xmax, ymax]=geoExtend
|
||||
center_x = (xmin + xmax) / 2.0
|
||||
center_y = (ymin + ymax) / 2.0
|
||||
center_point = [center_x, center_y]
|
||||
# 2. 计算能够覆盖整个矩形区域的最小半径(中心点到任一角点的最大距离)
|
||||
radius_to_corner = np.sqrt((xmax - center_x) ** 2 + (ymax - center_y) ** 2)
|
||||
|
||||
MLCFlag=False
|
||||
JLCFlag=False
|
||||
## MLC
|
||||
if MLCName in shipPortTree and not shipPortTree[MLCName] is None:
|
||||
# 3. 使用 query_ball_point 查找以中心点为圆心,radius_to_corner 为半径的圆内的所有点的索引
|
||||
potential_indices = shipPortTree[MLCName].query_ball_point(center_point, r=radius_to_corner)
|
||||
|
||||
# 4. 获取这些潜在点的实际坐标
|
||||
# 假设你的 KDTree 是从 data_points 构建的:MLCTree = KDTree(data_points)
|
||||
potential_points = shipPortTree[MLCName].data[potential_indices] # 这是所有潜在点的坐标数组
|
||||
|
||||
# 5. 进行精确的矩形范围过滤
|
||||
# 条件判断:x 坐标在 xmin 和 xmax 之间,且 y 坐标在 ymin 和 ymax 之间
|
||||
x_in_range = (potential_points[:, 0] >= xmin) & (potential_points[:, 0] <= xmax)
|
||||
y_in_range = (potential_points[:, 1] >= ymin) & (potential_points[:, 1] <= ymax)
|
||||
within_rect_indices_mask = x_in_range & y_in_range
|
||||
|
||||
# 6. 获取最终在矩形范围内的点的坐标(在原始 data_points 中的索引是 potential_indices[within_rect_indices_mask])
|
||||
final_points = potential_points[within_rect_indices_mask]
|
||||
|
||||
# final_points 就是你要的矩形范围内的点
|
||||
# 如果你需要的是这些点在原始数据中的索引,而不是坐标本身:
|
||||
final_indices = np.array(potential_indices)[within_rect_indices_mask]
|
||||
if final_points.shape[0]>0:
|
||||
MLCFlag=True
|
||||
with open(portTxtpath,"w",encoding="utf-8") as f:
|
||||
for i in range(final_points.shape[0]):
|
||||
f.write("{}\t\t{},{}\n".format("MLC",final_points[i,0],final_points[i,1]))
|
||||
pass
|
||||
if JLCName in shipPortTree and not shipPortTree[JLCName] is None:
|
||||
# 3. 使用 query_ball_point 查找以中心点为圆心,radius_to_corner 为半径的圆内的所有点的索引
|
||||
potential_indices = shipPortTree[JLCName].query_ball_point(center_point, r=radius_to_corner)
|
||||
|
||||
# 4. 获取这些潜在点的实际坐标
|
||||
# 假设你的 KDTree 是从 data_points 构建的:MLCTree = KDTree(data_points)
|
||||
potential_points = shipPortTree[JLCName].data[potential_indices] # 这是所有潜在点的坐标数组
|
||||
|
||||
# 5. 进行精确的矩形范围过滤
|
||||
# 条件判断:x 坐标在 xmin 和 xmax 之间,且 y 坐标在 ymin 和 ymax 之间
|
||||
x_in_range = (potential_points[:, 0] >= xmin) & (potential_points[:, 0] <= xmax)
|
||||
y_in_range = (potential_points[:, 1] >= ymin) & (potential_points[:, 1] <= ymax)
|
||||
within_rect_indices_mask = x_in_range & y_in_range
|
||||
|
||||
# 6. 获取最终在矩形范围内的点的坐标(在原始 data_points 中的索引是 potential_indices[within_rect_indices_mask])
|
||||
final_points = potential_points[within_rect_indices_mask]
|
||||
|
||||
# final_points 就是你要的矩形范围内的点
|
||||
# 如果你需要的是这些点在原始数据中的索引,而不是坐标本身:
|
||||
final_indices = np.array(potential_indices)[within_rect_indices_mask]
|
||||
if final_points.shape[0]>0:
|
||||
JLCFlag=True
|
||||
with open(portTxtpath,"a",encoding="utf-8") as f:
|
||||
for i in range(final_points.shape[0]):
|
||||
f.write("{}\t\t{},{}\n".format("JLC",final_points[i,0],final_points[i,1]))
|
||||
pass
|
||||
# 处理软件
|
||||
return MLCFlag,JLCFlag
|
||||
|
||||
|
||||
def getTiffInPort(shipPortTree,srcFolderPath_0img,outTiffInfoFilePath,outfolderPath):
|
||||
tiffpaths=find_tif_files_pathlib(srcFolderPath_0img)
|
||||
tiffLCPort={
|
||||
MLCName:[],
|
||||
JLCName:[],
|
||||
MJLCName:[],
|
||||
NOLCName:[]
|
||||
}
|
||||
for tiffpath in tiffpaths:
|
||||
MLCFlag,JLCFlag=getMJSignal(tiffpath,shipPortTree,outfolderPath)
|
||||
|
||||
if MLCFlag and JLCFlag:
|
||||
tiffLCPort[MJLCName].append(tiffpath)
|
||||
elif MLCFlag:
|
||||
tiffLCPort[MLCName].append(tiffpath)
|
||||
elif JLCFlag:
|
||||
tiffLCPort[JLCName].append(tiffpath)
|
||||
else:
|
||||
tiffLCPort[NOLCName].append(tiffpath)
|
||||
|
||||
# 输出文件
|
||||
with open(outTiffInfoFilePath,'w',encoding="utf-8") as f:
|
||||
for k in tiffLCPort:
|
||||
for tiffpath in tiffLCPort[k]:
|
||||
f.write("{}\t\t{}\n".format(k,tiffpath))
|
||||
|
||||
|
||||
|
||||
|
||||
def getMJSignal(geoExtend,shipPortTree):
|
||||
[xmin, ymin, xmax, ymax]=geoExtend
|
||||
center_x = (xmin + xmax) / 2.0
|
||||
center_y = (ymin + ymax) / 2.0
|
||||
center_point = [center_x, center_y]
|
||||
# 2. 计算能够覆盖整个矩形区域的最小半径(中心点到任一角点的最大距离)
|
||||
radius_to_corner = np.sqrt((xmax - center_x) ** 2 + (ymax - center_y) ** 2)
|
||||
|
||||
MLCFlag=False
|
||||
JLCFlag=False
|
||||
## MLC
|
||||
if MLCName in shipPortTree and not shipPortTree[MLCName] is None:
|
||||
# 3. 使用 query_ball_point 查找以中心点为圆心,radius_to_corner 为半径的圆内的所有点的索引
|
||||
potential_indices = shipPortTree[MLCName].query_ball_point(center_point, r=radius_to_corner)
|
||||
|
||||
# 4. 获取这些潜在点的实际坐标
|
||||
# 假设你的 KDTree 是从 data_points 构建的:MLCTree = KDTree(data_points)
|
||||
potential_points = shipPortTree[MLCName].data[potential_indices] # 这是所有潜在点的坐标数组
|
||||
|
||||
# 5. 进行精确的矩形范围过滤
|
||||
# 条件判断:x 坐标在 xmin 和 xmax 之间,且 y 坐标在 ymin 和 ymax 之间
|
||||
x_in_range = (potential_points[:, 0] >= xmin) & (potential_points[:, 0] <= xmax)
|
||||
y_in_range = (potential_points[:, 1] >= ymin) & (potential_points[:, 1] <= ymax)
|
||||
within_rect_indices_mask = x_in_range & y_in_range
|
||||
|
||||
# 6. 获取最终在矩形范围内的点的坐标(在原始 data_points 中的索引是 potential_indices[within_rect_indices_mask])
|
||||
final_points = potential_points[within_rect_indices_mask]
|
||||
|
||||
# final_points 就是你要的矩形范围内的点
|
||||
# 如果你需要的是这些点在原始数据中的索引,而不是坐标本身:
|
||||
final_indices = np.array(potential_indices)[within_rect_indices_mask]
|
||||
if final_points.shape[0]>0:
|
||||
MLCFlag=True
|
||||
# with open(portTxtpath,"w",encoding="utf-8") as f:
|
||||
# for i in range(final_points.shape[0]):
|
||||
# f.write("{}\t\t{},{}\n".format("MLC",final_points[i,0],final_points[i,1]))
|
||||
# pass
|
||||
if JLCName in shipPortTree and not shipPortTree[JLCName] is None:
|
||||
# 3. 使用 query_ball_point 查找以中心点为圆心,radius_to_corner 为半径的圆内的所有点的索引
|
||||
potential_indices = shipPortTree[JLCName].query_ball_point(center_point, r=radius_to_corner)
|
||||
|
||||
# 4. 获取这些潜在点的实际坐标
|
||||
# 假设你的 KDTree 是从 data_points 构建的:MLCTree = KDTree(data_points)
|
||||
potential_points = shipPortTree[JLCName].data[potential_indices] # 这是所有潜在点的坐标数组
|
||||
|
||||
# 5. 进行精确的矩形范围过滤
|
||||
# 条件判断:x 坐标在 xmin 和 xmax 之间,且 y 坐标在 ymin 和 ymax 之间
|
||||
x_in_range = (potential_points[:, 0] >= xmin) & (potential_points[:, 0] <= xmax)
|
||||
y_in_range = (potential_points[:, 1] >= ymin) & (potential_points[:, 1] <= ymax)
|
||||
within_rect_indices_mask = x_in_range & y_in_range
|
||||
|
||||
# 6. 获取最终在矩形范围内的点的坐标(在原始 data_points 中的索引是 potential_indices[within_rect_indices_mask])
|
||||
final_points = potential_points[within_rect_indices_mask]
|
||||
|
||||
# final_points 就是你要的矩形范围内的点
|
||||
# 如果你需要的是这些点在原始数据中的索引,而不是坐标本身:
|
||||
final_indices = np.array(potential_indices)[within_rect_indices_mask]
|
||||
if final_points.shape[0]>0:
|
||||
JLCFlag=True
|
||||
# with open(portTxtpath,"a",encoding="utf-8") as f:
|
||||
# for i in range(final_points.shape[0]):
|
||||
# f.write("{}\t\t{},{}\n".format("JLC",final_points[i,0],final_points[i,1]))
|
||||
# pass
|
||||
# 处理软件
|
||||
if MLCFlag and JLCFlag:
|
||||
return "mix_airport"
|
||||
# tiffLCPort[MJLCName].append(tiffpath)
|
||||
elif MLCFlag:
|
||||
return "civil_harbor"
|
||||
# tiffLCPort[MLCName].append(tiffpath)
|
||||
elif JLCFlag:
|
||||
return "military_harbor"
|
||||
# tiffLCPort[JLCName].append(tiffpath)
|
||||
else:
|
||||
return "no_harbor"
|
||||
# tiffLCPort[NOLCName].append(tiffpath)
|
||||
# return MLCFlag,JLCFlag
|
||||
|
||||
|
||||
|
||||
def shapefile_to_dota(shp_path, output_path, shipPortTree,difficulty_value=1):
|
||||
"""
|
||||
将Shapefile转换为DOTA格式
|
||||
:param shp_path: Shapefile文件路径
|
||||
:param output_path: 输出目录
|
||||
:param class_field: 类别字段名
|
||||
:param difficulty_value: 难度默认字段
|
||||
"""
|
||||
|
||||
# 注册所有驱动
|
||||
ogr.RegisterAll()
|
||||
|
||||
# 打开Shapefile文件
|
||||
driver = ogr.GetDriverByName('ESRI Shapefile')
|
||||
datasource = driver.Open(shp_path, 0)
|
||||
if datasource is None:
|
||||
print("无法打开Shapefile文件")
|
||||
return
|
||||
|
||||
# 获取图层
|
||||
layer = datasource.GetLayer()
|
||||
|
||||
output_file = output_path
|
||||
|
||||
with open(output_file, 'w',encoding="utf-8") as f:
|
||||
# 写入DOTA格式头信息(可选)
|
||||
# f.write('imagesource:unknown\n')
|
||||
# f.write('gsd:1.0\n')
|
||||
|
||||
# 遍历所有要素
|
||||
for feature in layer:
|
||||
# 获取几何对象
|
||||
geom = feature.GetGeometryRef()
|
||||
if geom is None:
|
||||
continue
|
||||
# 获取类别和难度
|
||||
try:
|
||||
class_name = 'unknown'
|
||||
except Exception as e:
|
||||
class_name="MLC"
|
||||
print(e)
|
||||
difficulty = difficulty_value
|
||||
|
||||
# 处理不同类型的几何图形
|
||||
if geom.GetGeometryName() == 'POLYGON':
|
||||
# 获取多边形外环
|
||||
ring = geom.GetGeometryRef(0)
|
||||
# 获取所有点
|
||||
points = []
|
||||
for i in range(ring.GetPointCount()):
|
||||
points.append(ring.GetPoint(i))
|
||||
|
||||
# 确保有足够的点(至少4个)
|
||||
if len(points) >= 4:
|
||||
# 取前4个点作为DOTA格式的四个角点
|
||||
# 注意: DOTA要求按顺序排列(顺时针或逆时针)
|
||||
x1, y1 = points[0][0], points[0][1]
|
||||
x2, y2 = points[1][0], points[1][1]
|
||||
x3, y3 = points[2][0], points[2][1]
|
||||
x4, y4 = points[3][0], points[3][1]
|
||||
|
||||
xmin = min(x1, x2,x3,x4)
|
||||
xmax = max(x1, x2,x3,x4)
|
||||
ymin = min(y1, y2,y3,y4)
|
||||
ymax = max(y1, y2,y3,y4)
|
||||
# [xmin, ymin, xmax, ymax] = geoExtend
|
||||
geoExtend = [xmin, ymin, xmax, ymax]
|
||||
class_name=getMJSignal(geoExtend, shipPortTree)
|
||||
# 写入DOTA格式行
|
||||
line = f"{x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4} {class_name} {difficulty}\n"
|
||||
f.write(line)
|
||||
|
||||
# 释放资源
|
||||
datasource.Destroy()
|
||||
print("转换完毕")
|
||||
|
||||
|
||||
def PortShapeProces(shp_path, output_path, MLCPath,JLCPath,JMLCPath,difficulty_value=1):
|
||||
shipPort={
|
||||
MLCName:getshapefileInfo(MLCPath),
|
||||
JLCName:getshapefileInfo(JLCPath),
|
||||
MJLCName:getshapefileInfo(JMLCPath), # 舰船不区分 居民一体
|
||||
}
|
||||
|
||||
shipPortTree={
|
||||
MLCName:KDTree(shipPort[MLCName]),
|
||||
JLCName:KDTree(shipPort[JLCName]),
|
||||
MJLCName:KDTree(shipPort[MJLCName]),
|
||||
}
|
||||
shapefile_to_dota(shp_path, output_path,shipPortTree, difficulty)
|
||||
|
||||
|
||||
|
||||
def getParams():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('-i','--infile',type=str,default=r'D:\港口\港口\Geo_bc2-sm-org-vv-20231016t135315-008424-0020e8-01.military_harbor.shp', help='输入shapefile文件')
|
||||
parser.add_argument('-o', '--outfile',type=str,default=r'D:\港口\港口dota\Geo_bc2-sm-org-vv-20231016t135315-008424-0020e8-01.military_harbor.txt', help='输出geojson文件')
|
||||
parser.add_argument('-m', '--mLC',type=str,help=r'MLC', default=r'D:\TYSAR-德清院\目标点位信息更新\0828目标点位\港口(民船).shp')
|
||||
parser.add_argument('-j', '--jLC',type=str,help=r'JLC' ,default=r'D:\TYSAR-德清院\目标点位信息更新\0828目标点位\军港.shp')
|
||||
parser.add_argument('-jm', '--jmlc',type=str,help=r'JMLC', default=r'D:\TYSAR-德清院\目标点位信息更新\0828目标点位\军民一体港口.shp')
|
||||
parser.add_argument('-d', '--difficulty',type=int,default=1, help='输出geojson文件')
|
||||
args = parser.parse_args()
|
||||
return args
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
parser = getParams()
|
||||
inFilePath=parser.infile
|
||||
outpath=parser.outfile
|
||||
mLCPath=parser.mLC
|
||||
jLCPath=parser.jLC
|
||||
jmLCPath=parser.jmlc
|
||||
difficulty=parser.difficulty
|
||||
print('infile=',inFilePath)
|
||||
print('outfile=',outpath)
|
||||
print('mLCPath=',mLCPath)
|
||||
print('jLCPath=',jLCPath)
|
||||
print('jmLCPath=',jmLCPath)
|
||||
print('difficulty=',difficulty)
|
||||
PortShapeProces(inFilePath, outpath, mLCPath, jLCPath, jmLCPath, difficulty_value=difficulty)
|
||||
exit(2)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
exit(3)
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
import os
|
||||
import argparse
|
||||
from osgeo import ogr,gdal
|
||||
from matplotlib import pyplot as plt
|
||||
from osgeo import gdal
|
||||
import matplotlib
|
||||
import matplotlib.patches as patches
|
||||
from osgeo import gdal
|
||||
from PIL import Image
|
||||
from scipy.spatial import cKDTree
|
||||
import numpy as np
|
||||
from tools.DotaOperator import DotaObj,createDota,readDotaFile,writerDotaFile
|
||||
import argparse
|
||||
import math
|
||||
from math import ceil, floor
|
||||
|
||||
pngpath=r"D:\港口\切片结果\Geo_bc2-sm-org-vv-20231016t135315-008424-0020e8-01_3.png"
|
||||
txtpath=r"D:\港口\切片结果\Geo_bc2-sm-org-vv-20231016t135315-008424-0020e8-01_3.txt"
|
||||
|
||||
|
||||
|
||||
pngdata=np.array(Image.open(pngpath))
|
||||
dotalist=readDotaFile(txtpath)
|
||||
|
||||
plt.figure()
|
||||
plt.imshow(pngdata)
|
||||
# 绘制每个目标的矩形框并标注坐标
|
||||
for i in range(len(dotalist)):
|
||||
# 提取x和y坐标
|
||||
x_coords = [dotalist[i].x1, dotalist[i].x2, dotalist[i].x3, dotalist[i].x4]
|
||||
y_coords = [dotalist[i].y1, dotalist[i].y2, dotalist[i].y3, dotalist[i].y4]
|
||||
|
||||
# 计算最小外接矩形(AABB)
|
||||
x_min, x_max = min(x_coords), max(x_coords)
|
||||
y_min, y_max = min(y_coords), max(y_coords)
|
||||
width = x_max - x_min
|
||||
height = y_max - y_min
|
||||
|
||||
# 绘制无填充矩形框(仅红色边框)
|
||||
rect = patches.Rectangle(
|
||||
(x_min, y_min), width, height,
|
||||
linewidth=2, edgecolor='red', facecolor='none' # 关键:facecolor='none'
|
||||
)
|
||||
plt.gca().add_patch(rect)
|
||||
|
||||
# ax.annotate(f'({x},{y})', xy=(x, y), xytext=(5, 5),
|
||||
# textcoords='offset points', fontsize=10,
|
||||
# bbox=dict(boxstyle='round,pad=0.5', fc='white', alpha=0.8))
|
||||
|
||||
# 在矩形中心标注目标编号
|
||||
center_x = sum(x_coords) / 4
|
||||
center_y = sum(y_coords) / 4
|
||||
plt.text(center_x, center_y, str(i),
|
||||
ha='center', va='center', fontsize=6, color='red')
|
||||
|
||||
|
||||
plt.show()
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
import numpy as np
|
||||
import os
|
||||
from glob import glob
|
||||
from pathlib import Path
|
||||
# from multiprocessing import Pool
|
||||
########################################################
|
||||
# 函数区
|
||||
########################################################
|
||||
|
||||
spacetySliceEnvPathExEPath=r"d:\ProgramData\anaconda3\envs\spacetySliceEnv\python.exe"
|
||||
|
||||
def find_tif_files_pathlib(directory):
|
||||
"""
|
||||
使用pathlib.Path.rglob递归查找指定目录下所有.tif和.tiff文件
|
||||
|
||||
参数:
|
||||
directory (str): 要搜索的根目录路径
|
||||
|
||||
返回:
|
||||
list: 包含所有找到的.tif/.tiff文件完整路径的列表
|
||||
"""
|
||||
path = Path(directory)
|
||||
# 使用rglob递归匹配所有.tif和.tiff文件
|
||||
tif_files = list(path.rglob('*.tif')) + list(path.rglob('*.tiff'))
|
||||
# 将Path对象转换为字符串路径
|
||||
return [str(file) for file in tif_files]
|
||||
|
||||
|
||||
def find_shp_files_pathlib(directory):
|
||||
"""
|
||||
使用pathlib.Path.rglob递归查找指定目录下所有.tif和.tiff文件
|
||||
|
||||
参数:
|
||||
directory (str): 要搜索的根目录路径
|
||||
|
||||
返回:
|
||||
list: 包含所有找到的.tif/.tiff文件完整路径的列表
|
||||
"""
|
||||
path = Path(directory)
|
||||
# 使用rglob递归匹配所有.tif和.tiff文件
|
||||
tif_files = list(path.rglob('*.shp'))
|
||||
# 将Path对象转换为字符串路径
|
||||
return [str(file) for file in tif_files]
|
||||
|
||||
|
||||
def preProcessLabelshapefile(shpfilepath,preFolderPath):
|
||||
if not os.path.exists(preFolderPath):
|
||||
os.makedirs(preFolderPath)
|
||||
file_path = Path(shpfilepath)
|
||||
directory_path = str(file_path.resolve().parent.name)
|
||||
|
||||
rootname = Path(shpfilepath).stem
|
||||
txtpath=os.path.join(preFolderPath,rootname+'.txt')
|
||||
programpath=r"R:\TYSAR-德清院\A-预处理-未标注\A0-算法版本\AA\SpacetySliceDataTools\LabelPortShipRasterSlice\Portshapefile2dota_AA.py"
|
||||
cmdtxt=r"{} {} -i {} -o {}".format(spacetySliceEnvPathExEPath,programpath,shpfilepath,txtpath)
|
||||
if os.system(cmdtxt) ==2:
|
||||
print("sucess:",cmdtxt)
|
||||
return "sucess: {}".format(cmdtxt)
|
||||
else:
|
||||
print("failed:",cmdtxt)
|
||||
return "failed: {}".format(cmdtxt)
|
||||
pass
|
||||
|
||||
|
||||
########################################################
|
||||
# 流程执行区
|
||||
########################################################
|
||||
if __name__ == '__main__':
|
||||
srcFolderPath = r"D:\港口\港口"
|
||||
preFolderPath= r"D:\港口\港口dota"
|
||||
shpPaths = find_shp_files_pathlib(srcFolderPath)
|
||||
for shppath in shpPaths:
|
||||
preProcessLabelshapefile(shppath, preFolderPath)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -118,14 +118,14 @@ def processPool(srcFolderPath,preFolderPath,targetfolderPath,logPath=r"R:\TYSAR-
|
|||
print("{}/{}".format(pidx+1,len(async_results)),async_result.get())
|
||||
writeoutlog(logPath,"{}/{} {}".format(pidx+1,len(async_results),async_result.get()))
|
||||
writeoutlog(logPath, "\nprocess finished \n")
|
||||
# moverTip,moveflag=moveDir(preFolderPath, targetfolderPath)
|
||||
# writeoutlog(logPath, moverTip)
|
||||
moverTip,moveflag=moveDir(preFolderPath, targetfolderPath)
|
||||
writeoutlog(logPath, moverTip)
|
||||
|
||||
writeoutlog(logPath, "====================================================================================\n")
|
||||
# if moveflag:
|
||||
# pass
|
||||
# else:
|
||||
# exit(3)
|
||||
if moveflag:
|
||||
pass
|
||||
else:
|
||||
exit(3)
|
||||
|
||||
########################################################
|
||||
# 流程执行区
|
||||
|
|
@ -146,16 +146,16 @@ if __name__ == '__main__':
|
|||
# processPool(srcFolderPath, preFolderPath,targetfolderPath, logPath)
|
||||
#
|
||||
# 20250826-不分类 条带模式
|
||||
srcFolderPath = r"R:\TYSAR-德清院\TYSAR-条带模式(SM)\航道\20250930-不分类\0-原图"
|
||||
preFolderPath = r"R:\TYSAR-德清院\TYSAR-条带模式(SM)\航道\20250930-不分类\A-预处理\AB-图像预处理"
|
||||
srcFolderPath = r"R:\TYSAR-德清院\TYSAR-条带模式(SM)\港口\20250826-不分类\0-原图"
|
||||
preFolderPath = r"D:\TYSAR-德清院\TYSAR-条带模式(SM)\港口\20250826-不分类\A-预处理\AB-图像预处理"
|
||||
targetfolderPath = r"R:\TYSAR-德清院\TYSAR-条带模式(SM)\港口\20250826-不分类\A-预处理\AB-图像预处理"
|
||||
processPool(srcFolderPath, preFolderPath, targetfolderPath,logPath)
|
||||
|
||||
# # 20250903-不分类 条带模式
|
||||
# srcFolderPath = r"R:\TYSAR-德清院\TYSAR-条带模式(SM)\港口\20250903-不分类\0-原图"
|
||||
# preFolderPath = r"D:\TYSAR-德清院\TYSAR-条带模式(SM)\港口\20250903-不分类\A-预处理\AB-图像预处理"
|
||||
# targetfolderPath = r"D:\TYSAR-德清院\TYSAR-条带模式(SM)\港口\20250903-不分类\A-预处理\AB-图像预处理"
|
||||
# processPool(srcFolderPath, preFolderPath,targetfolderPath, logPath)
|
||||
# 20250903-不分类 条带模式
|
||||
srcFolderPath = r"R:\TYSAR-德清院\TYSAR-条带模式(SM)\港口\20250903-不分类\0-原图"
|
||||
preFolderPath = r"D:\TYSAR-德清院\TYSAR-条带模式(SM)\港口\20250903-不分类\A-预处理\AB-图像预处理"
|
||||
targetfolderPath = r"D:\TYSAR-德清院\TYSAR-条带模式(SM)\港口\20250903-不分类\A-预处理\AB-图像预处理"
|
||||
processPool(srcFolderPath, preFolderPath,targetfolderPath, logPath)
|
||||
|
||||
# # 20250910-不分类 条带模式
|
||||
# srcFolderPath = r"R:\TYSAR-德清院\TYSAR-条带模式(SM)\港口\20250910-不分类\0-原图"
|
||||
|
|
@ -164,7 +164,7 @@ if __name__ == '__main__':
|
|||
# processPool(srcFolderPath, preFolderPath, targetfolderPath,logPath)
|
||||
|
||||
|
||||
result_flag_txt = r"R:\TYSAR-德清院\TYSAR-条带模式(SM)\航道\20250930-不分类\strechResult_finish.log"
|
||||
result_flag_txt = r"R:\TYSAR-德清院\TYSAR-条带模式(SM)\港口\strechResult_finish.log"
|
||||
with open(result_flag_txt,"w",encoding="utf-8") as f:
|
||||
f.write("strech finied!!!\n")
|
||||
writeoutlog(logPath, "strech finied!!!\n")
|
||||
|
|
|
|||
|
|
@ -1,143 +0,0 @@
|
|||
from opcode import opname
|
||||
|
||||
from osgeo import ogr
|
||||
import os
|
||||
import argparse
|
||||
from osgeo import ogr, gdal
|
||||
import os
|
||||
import argparse
|
||||
import numpy as np
|
||||
from scipy.spatial import KDTree
|
||||
from tools.DotaOperator import DotaObj,readDotaFile,writerDotaFile,createDota
|
||||
from glob import glob
|
||||
from pathlib import Path
|
||||
import shutil
|
||||
from tqdm import tqdm
|
||||
|
||||
|
||||
MLCName="MLC" # M
|
||||
JLCName="JLC" # J
|
||||
MJLCName="MJLC" # JM 混合
|
||||
NOLCName="NOLC" # 没有港口
|
||||
|
||||
|
||||
def existOrCreate(dirpath):
|
||||
if not os.path.exists(dirpath):
|
||||
os.makedirs(dirpath)
|
||||
|
||||
|
||||
def find_tifPort_files_pathlib(directory):
|
||||
path = Path(directory)
|
||||
# 使用rglob递归匹配所有.tif和.tiff文件
|
||||
tif_files = list(path.rglob('sumMJPort.txt'))
|
||||
# 将Path对象转换为字符串路径
|
||||
return [str(file) for file in tif_files]
|
||||
|
||||
|
||||
def find_label_files_pathlib(directory):
|
||||
path = Path(directory)
|
||||
# 使用rglob递归匹配所有.tif和.tiff文件
|
||||
tif_files = list(path.rglob('*.txt'))
|
||||
# 将Path对象转换为字符串路径
|
||||
return [str(file) for file in tif_files]
|
||||
|
||||
def read_MJPortFile(sumMJPortfilepath,deepsdict=None):
|
||||
lines=None
|
||||
with open(sumMJPortfilepath,'r',encoding="utf-8") as f:
|
||||
lines= f.readlines()
|
||||
if deepsdict is None :
|
||||
deepsdict={}
|
||||
for linestr in lines:
|
||||
if len(linestr)<3:
|
||||
continue
|
||||
clsname=linestr.split("\t\t")[0]
|
||||
tiffpath=linestr.split("\t\t")[1].replace("\n","")
|
||||
rootname=Path(tiffpath).stem
|
||||
deepsdict[rootname]=clsname
|
||||
return deepsdict
|
||||
|
||||
|
||||
|
||||
def SpliteProcess(srcfolderpath,infolderpath,outfolderpath):
|
||||
sumMJPortPaths=find_tifPort_files_pathlib(srcfolderpath)
|
||||
sumMJPortDict={}
|
||||
print("读取港口归属文件")
|
||||
for sumMJPortfilepath in tqdm(sumMJPortPaths):
|
||||
sumMJPortDict=read_MJPortFile(sumMJPortfilepath,sumMJPortDict)
|
||||
|
||||
labeltxtPaths=find_label_files_pathlib(infolderpath)
|
||||
|
||||
JportLabel=os.path.join(outfolderpath,'军港')
|
||||
MportLabel=os.path.join(outfolderpath,'民港')
|
||||
MJportLabel=os.path.join(outfolderpath,'混合港')
|
||||
NoportLabel=os.path.join(outfolderpath,'无港口')
|
||||
|
||||
existOrCreate(JportLabel)
|
||||
existOrCreate(MportLabel)
|
||||
existOrCreate(MJportLabel)
|
||||
existOrCreate(NoportLabel)
|
||||
|
||||
# 软件
|
||||
for labeltxtpath in tqdm(labeltxtPaths):
|
||||
rootname=Path(labeltxtpath).stem
|
||||
tiffpath=labeltxtpath.replace(".txt",".tif")
|
||||
if not os.path.exists(tiffpath):
|
||||
tiffpath=labeltxtpath.replace(".txt",".tiff")
|
||||
if not os.path.exists(tiffpath):
|
||||
print("error not fount: ",tiffpath)
|
||||
rootname=rootname.replace("_image.txt","").replace("_image","")
|
||||
idx=rootname.rfind("_")
|
||||
rootname=rootname[:idx]
|
||||
trgpath=None
|
||||
|
||||
if rootname in sumMJPortDict:
|
||||
clsname=sumMJPortDict[rootname]
|
||||
if MLCName == clsname: # M
|
||||
trgpath=MportLabel
|
||||
elif JLCName == clsname: # J
|
||||
trgpath=JportLabel
|
||||
elif MJLCName == clsname: # JM 混合
|
||||
trgpath=MJportLabel
|
||||
elif NOLCName == clsname: # 没有港口
|
||||
trgpath=NoportLabel
|
||||
clsname="MLC"
|
||||
else:
|
||||
print("error: ", Path(labeltxtpath).stem)
|
||||
continue
|
||||
|
||||
# shutil.copy(labeltxtpath, os.path.join(trgpath, os.path.basename(labeltxtpath)))
|
||||
newlabelpath=os.path.join(trgpath, os.path.basename(labeltxtpath))
|
||||
dotametas=readDotaFile(labeltxtpath)
|
||||
for dotaid in range(len(dotametas)):
|
||||
dotametas[dotaid].clsname=clsname
|
||||
writerDotaFile(dotametas,newlabelpath)
|
||||
shutil.copy(tiffpath, os.path.join(trgpath, os.path.basename(tiffpath)))
|
||||
else:
|
||||
print("error: ", Path(labeltxtpath).stem)
|
||||
|
||||
return True
|
||||
pass
|
||||
|
||||
|
||||
def getParams():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('-s','--srcfolder',type=str,default=r'D:\TYSAR-德清院\TYSAR-条带模式(SM)\港口', help='输入shapefile文件')
|
||||
parser.add_argument('-i','--inlabelfolder',type=str,default=r'R:\TYSAR-德清院\D-切片成果\TYSAR-条带模式(SM)\港口\切片结果整理', help='输入shapefile文件')
|
||||
parser.add_argument('-o', '--outfolder',type=str,default=r'R:\TYSAR-德清院\D-切片成果\TYSAR-条带模式(SM)\港口\舰船')
|
||||
args = parser.parse_args()
|
||||
return args
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
parser = getParams()
|
||||
srcfolder=parser.srcfolder
|
||||
infolder=parser.inlabelfolder
|
||||
outfolder=parser.outfolder
|
||||
print('srcfolder=',srcfolder)
|
||||
print('infolder=',infolder)
|
||||
print('outfolder=',outfolder)
|
||||
SpliteProcess(srcfolder,infolder,outfolder)
|
||||
exit(2)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
exit(3)
|
||||
|
|
@ -1,163 +0,0 @@
|
|||
import numpy as np
|
||||
import os
|
||||
from glob import glob
|
||||
from pathlib import Path
|
||||
from multiprocessing import Pool
|
||||
import hashlib # md5
|
||||
import time
|
||||
import shutil
|
||||
import datetime
|
||||
########################################################
|
||||
# 函数区
|
||||
########################################################
|
||||
|
||||
spacetySliceEnvPathExEPath=r"d:\ProgramData\anaconda3\envs\spacetySliceEnv\python.exe"
|
||||
|
||||
logPath=r"R:\TYSAR-德清院\A-预处理-未标注\A0-算法版本\AA\SpacetySliceDataTools\log\process.log"
|
||||
|
||||
|
||||
def existOrCreate(dirpath):
|
||||
if not os.path.exists(dirpath):
|
||||
os.makedirs(dirpath)
|
||||
|
||||
def moveDir(srcfolderPath,targetfolderPath):
|
||||
try:
|
||||
shutil.copytree(srcfolderPath,targetfolderPath,dirs_exist_ok=True)
|
||||
print("sucess: copy ", srcfolderPath,targetfolderPath )
|
||||
shutil.rmtree(srcfolderPath)
|
||||
print("sucess: rmtree ", srcfolderPath)
|
||||
return "sucess: copy and rmtree from {} to {}".format(srcfolderPath,targetfolderPath),True
|
||||
except Exception as e:
|
||||
print("failed: copy ", srcfolderPath, targetfolderPath)
|
||||
return "failed: copy and rmtree from {} to {}".format(srcfolderPath,targetfolderPath),False
|
||||
|
||||
def writeoutlog(logPath,cmdtxt):
|
||||
with open(logPath,'a',encoding="utf-8") as f:
|
||||
f.write(cmdtxt)
|
||||
f.write("\n")
|
||||
|
||||
|
||||
def preProcessTiFF(tiffpath,txtpath,preFolderPath):
|
||||
|
||||
file_path = Path(tiffpath)
|
||||
directory_path = str(file_path.resolve().parent.name)
|
||||
rootname=Path(tiffpath).stem
|
||||
outpngpath=os.path.join(preFolderPath,"I"+directory_path+"_"+rootname+'.png')
|
||||
programpath=r"R:\TYSAR-德清院\A-预处理-未标注\A0-算法版本\AA\SpacetySliceDataTools\generatorRasterSlicesTools\SpacetyTIFFDataStretch2PNG_AC.py"
|
||||
|
||||
# cmdtxt=r"{} {} -i {} -o {} --filemode --SquareRoot".format(spacetySliceEnvPathExEPath,programpath,tiffpath,outpngpath)
|
||||
cmdtxt=r"{} {} -i {} -p {} -o {} --slicemode --SquareRoot".format(
|
||||
spacetySliceEnvPathExEPath,programpath,
|
||||
tiffpath,
|
||||
txtpath,
|
||||
preFolderPath
|
||||
) # 直接切片
|
||||
if os.system(cmdtxt) ==2:
|
||||
print("sucess:",cmdtxt)
|
||||
writeoutlog(logPath, "sucess: {}\n".format(cmdtxt))
|
||||
return 2
|
||||
else:
|
||||
print("failed:",cmdtxt)
|
||||
writeoutlog(logPath, "failed: {}\n".format(cmdtxt))
|
||||
return 3
|
||||
|
||||
|
||||
def processMJPort(srcFolderPath,outMJPortSumTxtPath,outMJPortFolderPath,MLCShapeFilePath,JLCShapeFilePath,MJLCShapeFilePath):
|
||||
programpath = r"R:\TYSAR-德清院\A-预处理-未标注\A0-算法版本\AA\SpacetySliceDataTools\generatorRasterSlicesTools\SplitShipPortRasterTools_AC.py"
|
||||
cmdtxt=r"{} {} -s {} -o {} -f {} -m {} -j {} -jm {}".format(
|
||||
spacetySliceEnvPathExEPath,programpath,
|
||||
srcFolderPath,outMJPortSumTxtPath,outMJPortFolderPath,
|
||||
MLCShapeFilePath, JLCShapeFilePath, MJLCShapeFilePath
|
||||
)
|
||||
if os.system(cmdtxt) ==2:
|
||||
print("sucess:",cmdtxt)
|
||||
writeoutlog(logPath, "sucess: {}\n".format(cmdtxt))
|
||||
# return "sucess: {}".format(cmdtxt)
|
||||
return 2
|
||||
else:
|
||||
print("failed:",cmdtxt)
|
||||
writeoutlog(logPath, "failed: {}\n".format(cmdtxt))
|
||||
# return "failed: {}".format(cmdtxt)
|
||||
return 3
|
||||
|
||||
|
||||
def preProcessShipPortTools(srcFolderPath,targetFolderPath,outTargetFolderPath):
|
||||
writeoutlog(logPath, "====================================================================================\n")
|
||||
writeoutlog(logPath, "time: {}".format(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")))
|
||||
writeoutlog(logPath, "srcFolderPath: {}".format(srcFolderPath))
|
||||
writeoutlog(logPath, "targetFolderPath: {}".format(targetFolderPath))
|
||||
writeoutlog(logPath, "process start \n")
|
||||
#
|
||||
# # 文件接口创建
|
||||
# MPortFolder=os.path.join(targetFolderPath,"AC-图像预处理","民港口")
|
||||
# JPortFolder=os.path.join(targetFolderPath,"AC-图像预处理","军港口")
|
||||
# MJPortFolder=os.path.join(targetFolderPath,"AC-图像预处理","混合港口")
|
||||
# NoPortFolder=os.path.join(targetFolderPath,"AC-图像预处理","无港口")
|
||||
#
|
||||
# existOrCreate(MPortFolder)
|
||||
# existOrCreate(JPortFolder)
|
||||
# existOrCreate(MJPortFolder)
|
||||
# existOrCreate(NoPortFolder)
|
||||
|
||||
outMJPortSumTxtPath=os.path.join(targetFolderPath,"AC-图像预处理","sumMJPort.txt")
|
||||
outMJPortFolderPath=os.path.join(targetFolderPath,"AC-图像预处理","sumMJPortFolder")
|
||||
|
||||
existOrCreate(outMJPortFolderPath)
|
||||
|
||||
MLCShapeFilePath=r"D:\TYSAR-德清院\目标点位信息更新\0828目标点位\港口(民船).shp"
|
||||
JLCShapeFilePath=r"D:\TYSAR-德清院\目标点位信息更新\0828目标点位\军港.shp"
|
||||
MJLCShapeFilePath=r"D:\TYSAR-德清院\目标点位信息更新\0828目标点位\军民一体港口.shp"
|
||||
|
||||
processMJPortflag=processMJPort(srcFolderPath,outMJPortSumTxtPath,outMJPortFolderPath,MLCShapeFilePath,JLCShapeFilePath,MJLCShapeFilePath)
|
||||
|
||||
writeoutlog(logPath, "\nprocess finished \n")
|
||||
# moverTip,moveflag=moveDir(targetFolderPath, outTargetFolderPath)
|
||||
# writeoutlog(logPath, moverTip)
|
||||
writeoutlog(logPath, "====================================================================================\n")
|
||||
# if moveflag:
|
||||
# pass
|
||||
# else:
|
||||
# exit(3)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
# 20250813-不分类 条带模式
|
||||
srcFolderPath = r"R:\TYSAR-德清院\TYSAR-条带模式(SM)\港口\20250813-不分类\0-原图"
|
||||
preFolderPath = r"D:\TYSAR-德清院\TYSAR-条带模式(SM)\港口\20250813-不分类\A-预处理\AB-图像预处理"
|
||||
targetfolderPath = r"D:\TYSAR-德清院\TYSAR-条带模式(SM)\港口\20250813-不分类\A-预处理\AB-图像预处理"
|
||||
preProcessShipPortTools(srcFolderPath, preFolderPath, targetfolderPath)
|
||||
#
|
||||
# 20250818 条带模式
|
||||
srcFolderPath = r"R:\TYSAR-德清院\TYSAR-条带模式(SM)\港口\20250818-不分类\0-原图"
|
||||
preFolderPath = r"D:\TYSAR-德清院\TYSAR-条带模式(SM)\港口\20250818-不分类\A-预处理\AB-图像预处理"
|
||||
targetfolderPath = r"R:\TYSAR-德清院\TYSAR-条带模式(SM)\港口\20250818-不分类\A-预处理\AB-图像预处理"
|
||||
preProcessShipPortTools(srcFolderPath, preFolderPath,targetfolderPath)
|
||||
#
|
||||
# 20250826-不分类 条带模式
|
||||
srcFolderPath = r"R:\TYSAR-德清院\TYSAR-条带模式(SM)\港口\20250826-不分类\0-原图"
|
||||
preFolderPath = r"D:\TYSAR-德清院\TYSAR-条带模式(SM)\港口\20250826-不分类\A-预处理"
|
||||
targetfolderPath = r"R:\TYSAR-德清院\TYSAR-条带模式(SM)\港口\20250826-不分类\A-预处理"
|
||||
preProcessShipPortTools(srcFolderPath, preFolderPath,targetfolderPath)
|
||||
#
|
||||
# 20250903-不分类条带模式
|
||||
srcFolderPath = r"R:\TYSAR-德清院\TYSAR-条带模式(SM)\港口\20250903-不分类\0-原图"
|
||||
preFolderPath = r"D:\TYSAR-德清院\TYSAR-条带模式(SM)\港口\20250903-不分类\A-预处理"
|
||||
targetfolderPath = r"R:\TYSAR-德清院\TYSAR-条带模式(SM)\港口\20250903-不分类\A-预处理"
|
||||
preProcessShipPortTools(srcFolderPath, preFolderPath,targetfolderPath)
|
||||
#
|
||||
# 20250910-不分类 条带模式
|
||||
srcFolderPath = r"R:\TYSAR-德清院\TYSAR-条带模式(SM)\港口\20250910-不分类\0-原图"
|
||||
preFolderPath = r"D:\TYSAR-德清院\TYSAR-条带模式(SM)\港口\20250910-不分类\A-预处理"
|
||||
targetfolderPath = r"R:\TYSAR-德清院\TYSAR-条带模式(SM)\港口\20250910-不分类\A-预处理"
|
||||
preProcessShipPortTools(srcFolderPath, preFolderPath,targetfolderPath)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,197 +0,0 @@
|
|||
import numpy as np
|
||||
import os
|
||||
from glob import glob
|
||||
from pathlib import Path
|
||||
from multiprocessing import Pool
|
||||
import hashlib # md5
|
||||
import time
|
||||
import shutil
|
||||
import datetime
|
||||
########################################################
|
||||
# 函数区
|
||||
########################################################
|
||||
|
||||
spacetySliceEnvPathExEPath=r"d:\ProgramData\anaconda3\envs\spacetySliceEnv\python.exe"
|
||||
|
||||
logPath=r"R:\TYSAR-德清院\A-预处理-未标注\A0-算法版本\AA\SpacetySliceDataTools\log\process.log"
|
||||
|
||||
|
||||
def existOrCreate(dirpath):
|
||||
if not os.path.exists(dirpath):
|
||||
os.makedirs(dirpath)
|
||||
|
||||
def moveDir(srcfolderPath,targetfolderPath):
|
||||
try:
|
||||
shutil.copytree(srcfolderPath,targetfolderPath,dirs_exist_ok=True)
|
||||
print("sucess: copy ", srcfolderPath,targetfolderPath )
|
||||
shutil.rmtree(srcfolderPath)
|
||||
print("sucess: rmtree ", srcfolderPath)
|
||||
return "sucess: copy and rmtree from {} to {}".format(srcfolderPath,targetfolderPath),True
|
||||
except Exception as e:
|
||||
print("failed: copy ", srcfolderPath, targetfolderPath)
|
||||
return "failed: copy and rmtree from {} to {}".format(srcfolderPath,targetfolderPath),False
|
||||
|
||||
def writeoutlog(logPath,cmdtxt):
|
||||
with open(logPath,'a',encoding="utf-8") as f:
|
||||
f.write(cmdtxt)
|
||||
f.write("\n")
|
||||
|
||||
|
||||
def preProcessTiFF(tiffpath,txtpath,preFolderPath):
|
||||
|
||||
file_path = Path(tiffpath)
|
||||
directory_path = str(file_path.resolve().parent.name)
|
||||
rootname=Path(tiffpath).stem
|
||||
outpngpath=os.path.join(preFolderPath,"I"+directory_path+"_"+rootname+'.png')
|
||||
programpath=r"R:\TYSAR-德清院\A-预处理-未标注\A0-算法版本\AA\SpacetySliceDataTools\generatorRasterSlicesTools\SpacetyTIFFDataStretch2PNG_AC.py"
|
||||
|
||||
# cmdtxt=r"{} {} -i {} -o {} --filemode --SquareRoot".format(spacetySliceEnvPathExEPath,programpath,tiffpath,outpngpath)
|
||||
cmdtxt=r"{} {} -i {} -p {} -o {} --slicemode --SquareRoot".format(
|
||||
spacetySliceEnvPathExEPath,programpath,
|
||||
tiffpath,
|
||||
txtpath,
|
||||
preFolderPath
|
||||
) # 直接切片
|
||||
if os.system(cmdtxt) ==2:
|
||||
print("sucess:",cmdtxt)
|
||||
writeoutlog(logPath, "sucess: {}\n".format(cmdtxt))
|
||||
return "sucess: {}\n".format(cmdtxt)
|
||||
else:
|
||||
print("failed:",cmdtxt)
|
||||
writeoutlog(logPath, "failed: {}\n".format(cmdtxt))
|
||||
return "failed: {}\n".format(cmdtxt)
|
||||
|
||||
|
||||
def processMJPort(srcFolderPath,outMJPortSumTxtPath,outMJPortFolderPath,MLCShapeFilePath,JLCShapeFilePath,MJLCShapeFilePath):
|
||||
programpath = r"R:\TYSAR-德清院\A-预处理-未标注\A0-算法版本\AA\SpacetySliceDataTools\generatorRasterSlicesTools\SplitShipPortRasterTools_AC.py"
|
||||
cmdtxt=r"{} {} -s {} -o {} -f {} -m {} -j {} -jm {}".format(
|
||||
spacetySliceEnvPathExEPath,programpath,
|
||||
srcFolderPath,outMJPortSumTxtPath,outMJPortFolderPath,
|
||||
MLCShapeFilePath, JLCShapeFilePath, MJLCShapeFilePath
|
||||
)
|
||||
if os.system(cmdtxt) ==2:
|
||||
print("sucess:",cmdtxt)
|
||||
writeoutlog(logPath, "sucess: {}\n".format(cmdtxt))
|
||||
# return "sucess: {}".format(cmdtxt)
|
||||
return 2
|
||||
else:
|
||||
print("failed:",cmdtxt)
|
||||
writeoutlog(logPath, "failed: {}\n".format(cmdtxt))
|
||||
# return "failed: {}".format(cmdtxt)
|
||||
return 3
|
||||
|
||||
|
||||
def preProcessShipPortTools(srcFolderPath,targetFolderPath,outTargetFolderPath):
|
||||
writeoutlog(logPath, "====================================================================================\n")
|
||||
writeoutlog(logPath, "time: {}".format(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")))
|
||||
writeoutlog(logPath, "srcFolderPath: {}".format(srcFolderPath))
|
||||
writeoutlog(logPath, "targetFolderPath: {}".format(targetFolderPath))
|
||||
writeoutlog(logPath, "process start \n")
|
||||
|
||||
# 文件接口创建
|
||||
MPortFolder=os.path.join(targetFolderPath,"AC-图像预处理","民港口")
|
||||
JPortFolder=os.path.join(targetFolderPath,"AC-图像预处理","军港口")
|
||||
MJPortFolder=os.path.join(targetFolderPath,"AC-图像预处理","混合港口")
|
||||
NoPortFolder=os.path.join(targetFolderPath,"AC-图像预处理","无港口")
|
||||
|
||||
existOrCreate(MPortFolder)
|
||||
existOrCreate(JPortFolder)
|
||||
existOrCreate(MJPortFolder)
|
||||
existOrCreate(NoPortFolder)
|
||||
|
||||
outMJPortSumTxtPath=os.path.join(targetFolderPath,"AC-图像预处理","sumMJPort.txt")
|
||||
outMJPortFolderPath=os.path.join(targetFolderPath,"AC-图像预处理","sumMJPortFolder")
|
||||
|
||||
existOrCreate(outMJPortFolderPath)
|
||||
|
||||
MLCShapeFilePath=r"D:\TYSAR-德清院\目标点位信息更新\0828目标点位\港口(民船).shp"
|
||||
JLCShapeFilePath=r"D:\TYSAR-德清院\目标点位信息更新\0828目标点位\军港.shp" # 数据BM,不公开
|
||||
MJLCShapeFilePath=r"D:\TYSAR-德清院\目标点位信息更新\0828目标点位\军民一体港口.shp"
|
||||
processMJPortflag=2
|
||||
# processMJPortflag=processMJPort(srcFolderPath,outMJPortSumTxtPath,outMJPortFolderPath,MLCShapeFilePath,JLCShapeFilePath,MJLCShapeFilePath)
|
||||
# 港口归属
|
||||
if processMJPortflag==2:
|
||||
# 逐行处理
|
||||
MJlines=None
|
||||
with open(outMJPortSumTxtPath,"r",encoding="utf-8") as f:
|
||||
MJlines=f.readlines()
|
||||
|
||||
MLCName = "MLC" # M
|
||||
JLCName = "JLC" # J
|
||||
MJLCName = "MJLC" # JM 混合
|
||||
NOLCName = "NOLC" # 没有港口
|
||||
|
||||
async_results = []
|
||||
with Pool(processes=6) as pool:
|
||||
for linestr in MJlines:
|
||||
if len(linestr)>3:
|
||||
clsname=linestr.split("\t\t")[0]
|
||||
tiffpath=linestr.split("\t\t")[1].replace("\n","")
|
||||
rootname=Path(tiffpath).stem
|
||||
portTxtpath = os.path.join(outMJPortFolderPath, rootname + ".txt")
|
||||
tarPortFolder=None
|
||||
if clsname==MLCName:
|
||||
tarPortFolder=MPortFolder
|
||||
elif clsname==JLCName:
|
||||
tarPortFolder=JPortFolder
|
||||
elif clsname==MJLCName:
|
||||
tarPortFolder=MJPortFolder
|
||||
elif clsname==NOLCName:
|
||||
tarPortFolder=NoPortFolder
|
||||
else:
|
||||
continue
|
||||
async_results.append(preProcessTiFF(tiffpath,portTxtpath,tarPortFolder))
|
||||
else:
|
||||
continue
|
||||
# 处理分块
|
||||
for pidx in range(len(async_results)):
|
||||
async_result=async_results[pidx]
|
||||
print("{}/{}".format(pidx+1,len(async_results)))
|
||||
# writeoutlog(logPath,"{}/{}".format(pidx+1,len(async_results),async_result.get()))
|
||||
pass
|
||||
else:
|
||||
pass
|
||||
|
||||
writeoutlog(logPath, "\nprocess finished \n")
|
||||
# moverTip,moveflag=moveDir(targetFolderPath, outTargetFolderPath)
|
||||
# writeoutlog(logPath, moverTip)
|
||||
writeoutlog(logPath, "====================================================================================\n")
|
||||
# if moveflag:
|
||||
# pass
|
||||
# else:
|
||||
# exit(3)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
# 20250813-不分类 条带模式
|
||||
# srcFolderPath = r"R:\TYSAR-德清院\TYSAR-条带模式(SM)\港口\20250813-不分类\0-原图"
|
||||
# preFolderPath = r"D:\TYSAR-德清院\TYSAR-条带模式(SM)\港口\20250813-不分类\A-预处理\AB-图像预处理"
|
||||
# targetfolderPath = r"D:\TYSAR-德清院\TYSAR-条带模式(SM)\港口\20250813-不分类\A-预处理\AB-图像预处理"
|
||||
# preProcessShipPortTools(srcFolderPath, preFolderPath, targetfolderPath,logPath)
|
||||
#
|
||||
# # 20250818 条带模式
|
||||
# srcFolderPath = r"R:\TYSAR-德清院\TYSAR-条带模式(SM)\港口\20250818-不分类\0-原图"
|
||||
# preFolderPath = r"D:\TYSAR-德清院\TYSAR-条带模式(SM)\港口\20250818-不分类\A-预处理\AB-图像预处理"
|
||||
# targetfolderPath = r"R:\TYSAR-德清院\TYSAR-条带模式(SM)\港口\20250818-不分类\A-预处理\AB-图像预处理"
|
||||
# preProcessShipPortTools(srcFolderPath, preFolderPath,targetfolderPath, logPath)
|
||||
#
|
||||
# 20250826-不分类 条带模式
|
||||
# srcFolderPath = r"R:\TYSAR-德清院\TYSAR-条带模式(SM)\港口\20250826-不分类\0-原图"
|
||||
# preFolderPath = r"D:\TYSAR-德清院\TYSAR-条带模式(SM)\港口\20250826-不分类\A-预处理"
|
||||
# targetfolderPath = r"R:\TYSAR-德清院\TYSAR-条带模式(SM)\港口\20250826-不分类\A-预处理"
|
||||
# preProcessShipPortTools(srcFolderPath, preFolderPath, targetfolderPath)
|
||||
|
||||
# 20250930-不分类 条带模式
|
||||
srcFolderPath = r"R:\TYSAR-德清院\TYSAR-条带模式(SM)\航道\20250930-不分类\0-原图"
|
||||
preFolderPath = r"R:\TYSAR-德清院\TYSAR-条带模式(SM)\航道\20250930-不分类\A-预处理2"
|
||||
targetfolderPath = r"R:\TYSAR-德清院\TYSAR-条带模式(SM)\港口\20250826-不分类\A-预处理"
|
||||
preProcessShipPortTools(srcFolderPath, preFolderPath, targetfolderPath)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,621 +0,0 @@
|
|||
"""
|
||||
|
||||
2025.09.16 切片增加后缀 _image.png _image.tiff
|
||||
2025.09.22 增加港口切片要求
|
||||
|
||||
"""
|
||||
from osgeo import ogr, gdal
|
||||
import os
|
||||
import argparse
|
||||
import numpy as np
|
||||
from PIL import Image
|
||||
import math
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
portsliceSize=5000
|
||||
shipsliceSize=1024
|
||||
BlockOverLayer=0.25
|
||||
|
||||
def existOrCreate(dirpath):
|
||||
if not os.path.exists(dirpath):
|
||||
os.makedirs(dirpath)
|
||||
|
||||
|
||||
def get_filename_without_ext(path):
|
||||
base_name = os.path.basename(path)
|
||||
if '.' not in base_name or base_name.startswith('.'):
|
||||
return base_name
|
||||
return base_name.rsplit('.', 1)[0]
|
||||
|
||||
def read_tif(path):
|
||||
dataset = gdal.Open(path) # 打开TIF文件
|
||||
if dataset is None:
|
||||
print("无法打开文件")
|
||||
return None, None, None
|
||||
|
||||
cols = dataset.RasterXSize # 图像宽度
|
||||
rows = dataset.RasterYSize # 图像高度
|
||||
bands = dataset.RasterCount
|
||||
im_proj = dataset.GetProjection() # 获取投影信息
|
||||
im_Geotrans = dataset.GetGeoTransform() # 获取仿射变换信息
|
||||
im_data = dataset.ReadAsArray(0, 0, cols, rows) # 读取栅格数据为NumPy数组
|
||||
print("行数:", rows)
|
||||
print("列数:", cols)
|
||||
print("波段:", bands)
|
||||
del dataset # 关闭数据集
|
||||
return im_proj, im_Geotrans, im_data
|
||||
|
||||
def write_envi(im_data, im_geotrans, im_proj, output_path):
|
||||
"""
|
||||
将数组数据写入ENVI格式文件
|
||||
:param im_data: 输入的numpy数组(2D或3D)
|
||||
:param im_geotrans: 仿射变换参数(6元组)
|
||||
:param im_proj: 投影信息(WKT字符串)
|
||||
:param output_path: 输出文件路径(无需扩展名,会自动生成.dat和.hdr)
|
||||
"""
|
||||
im_bands = 1
|
||||
im_height, im_width = im_data.shape
|
||||
# 创建ENVI格式驱动
|
||||
driver = gdal.GetDriverByName("GTiff")
|
||||
dataset = driver.Create(output_path, im_width, im_height, 1, gdal.GDT_Byte)
|
||||
|
||||
if dataset is not None:
|
||||
dataset.SetGeoTransform(im_geotrans) # 设置地理变换参数
|
||||
dataset.SetProjection(im_proj) # 设置投影
|
||||
|
||||
dataset.GetRasterBand(1).WriteArray(im_data)
|
||||
|
||||
dataset.FlushCache() # 确保数据写入磁盘
|
||||
dataset = None # 关闭文件
|
||||
|
||||
|
||||
def write_allExtend(im_data, im_geotrans, im_proj, output_path):
|
||||
"""
|
||||
将数组数据写入ENVI格式文件
|
||||
:param im_data: 输入的numpy数组(2D或3D)
|
||||
:param im_geotrans: 仿射变换参数(6元组)
|
||||
:param im_proj: 投影信息(WKT字符串)
|
||||
:param output_path: 输出文件路径(无需扩展名,会自动生成.dat和.hdr)
|
||||
"""
|
||||
im_bands = 1
|
||||
im_height, im_width = im_data.shape
|
||||
|
||||
create_options=[
|
||||
"COMPRESS=DEFLATE",
|
||||
"PREDICTOR=2",
|
||||
"ZLEVEL=6",
|
||||
"TILED=YES",
|
||||
]
|
||||
|
||||
# 创建ENVI格式驱动
|
||||
driver = gdal.GetDriverByName("GTiff")
|
||||
dataset = driver.Create(output_path, im_width, im_height, 1, gdal.GDT_Byte,options=create_options)
|
||||
|
||||
if dataset is not None:
|
||||
dataset.SetGeoTransform(im_geotrans) # 设置地理变换参数
|
||||
dataset.SetProjection(im_proj) # 设置投影
|
||||
|
||||
dataset.GetRasterBand(1).WriteArray(im_data)
|
||||
|
||||
dataset.FlushCache() # 确保数据写入磁盘
|
||||
dataset = None # 关闭文件
|
||||
|
||||
|
||||
def write_tiff(im_data, im_geotrans, im_proj, output_path):
|
||||
"""
|
||||
将数组数据写入ENVI格式文件
|
||||
:param im_data: 输入的numpy数组(2D或3D)
|
||||
:param im_geotrans: 仿射变换参数(6元组)
|
||||
:param im_proj: 投影信息(WKT字符串)
|
||||
:param output_path: 输出文件路径(无需扩展名,会自动生成.dat和.hdr)
|
||||
"""
|
||||
im_bands = 1
|
||||
im_height, im_width = im_data.shape
|
||||
# 创建ENVI格式驱动
|
||||
driver = gdal.GetDriverByName("GTiff")
|
||||
dataset = driver.Create(output_path, im_width, im_height, 1, gdal.GDT_Float32)
|
||||
|
||||
if dataset is not None:
|
||||
dataset.SetGeoTransform(im_geotrans) # 设置地理变换参数
|
||||
dataset.SetProjection(im_proj) # 设置投影
|
||||
|
||||
dataset.GetRasterBand(1).WriteArray(im_data)
|
||||
|
||||
dataset.FlushCache() # 确保数据写入磁盘
|
||||
dataset = None # 关闭文件
|
||||
|
||||
|
||||
def Strech_linear(im_data):
|
||||
im_data_dB=10*np.log10(im_data)
|
||||
immask=np.isfinite(im_data_dB)
|
||||
infmask = np.isinf(im_data_dB)
|
||||
imvail_data=im_data[immask]
|
||||
im_data_dB=0
|
||||
|
||||
minvalue=np.nanmin(imvail_data)
|
||||
maxvalue=np.nanmax(imvail_data)
|
||||
|
||||
infmask = np.isinf(im_data_dB)
|
||||
im_data[infmask] = minvalue-100
|
||||
im_data = (im_data - minvalue) / (maxvalue - minvalue) * 254+1
|
||||
im_data=np.clip(im_data,0,255)
|
||||
return im_data.astype(np.uint8)
|
||||
|
||||
def Strech_linear1(im_data):
|
||||
im_data_dB = 10 * np.log10(im_data)
|
||||
immask = np.isfinite(im_data_dB)
|
||||
infmask = np.isinf(im_data_dB)
|
||||
imvail_data = im_data[immask]
|
||||
im_data_dB=0
|
||||
|
||||
minvalue=np.percentile(imvail_data,1)
|
||||
maxvalue = np.percentile(imvail_data, 99)
|
||||
|
||||
|
||||
im_data[infmask] = minvalue - 100
|
||||
im_data = (im_data - minvalue) / (maxvalue - minvalue) * 254 + 1
|
||||
im_data = np.clip(im_data, 0, 255)
|
||||
|
||||
return im_data.astype(np.uint8)
|
||||
|
||||
|
||||
def Strech_linear2(im_data):
|
||||
im_data_dB = 10 * np.log10(im_data)
|
||||
immask = np.isfinite(im_data_dB)
|
||||
infmask = np.isinf(im_data_dB)
|
||||
imvail_data = im_data[immask]
|
||||
im_data_dB = 0
|
||||
|
||||
minvalue = np.percentile(imvail_data, 2)
|
||||
maxvalue = np.percentile(imvail_data, 98)
|
||||
|
||||
im_data[infmask] = minvalue - 100
|
||||
im_data = (im_data - minvalue) / (maxvalue - minvalue) * 254 + 1
|
||||
im_data = np.clip(im_data, 0, 255)
|
||||
|
||||
return im_data.astype(np.uint8)
|
||||
|
||||
def Strech_linear5(im_data):
|
||||
im_data_dB = 10 * np.log10(im_data)
|
||||
immask = np.isfinite(im_data_dB)
|
||||
infmask = np.isinf(im_data_dB)
|
||||
imvail_data = im_data[immask]
|
||||
im_data_dB = 0
|
||||
|
||||
minvalue = np.percentile(imvail_data, 5)
|
||||
maxvalue = np.percentile(imvail_data, 95)
|
||||
|
||||
im_data[infmask] = minvalue - 100
|
||||
im_data = (im_data - minvalue) / (maxvalue - minvalue) * 254 + 1
|
||||
im_data = np.clip(im_data, 0, 255)
|
||||
|
||||
return im_data.astype(np.uint8)
|
||||
|
||||
def Strech_SquareRoot(im_data):
|
||||
# 判断是否为dB
|
||||
# immask = np.isfinite(im_data)
|
||||
# imvail_data = im_data[immask]
|
||||
# minvalue = np.percentile(imvail_data,30)
|
||||
# if minvalue<0 :
|
||||
# im_data=np.power(10.0,im_data/10.0)
|
||||
|
||||
im_data=np.sqrt(im_data)
|
||||
immask = np.isfinite(im_data)
|
||||
imvail_data = im_data[immask]
|
||||
|
||||
minvalue=np.nanmin(imvail_data)
|
||||
maxvalue=np.nanmax(imvail_data)
|
||||
minvalue_01Prec = np.percentile(imvail_data, 2) # 20250904 1%拉伸
|
||||
maxvalue_999Prec = np.percentile(imvail_data, 98)
|
||||
print('sqrt root min - max ', minvalue,maxvalue)
|
||||
if (maxvalue-minvalue)/(maxvalue_999Prec-minvalue_01Prec)>3: # 表示 拉伸之后,像素值绝大部分很有可能集中在 80
|
||||
minvalue=minvalue_01Prec
|
||||
maxvalue=maxvalue_999Prec
|
||||
print('sqrt root min(0.1) - max(99.9) ', minvalue, maxvalue)
|
||||
|
||||
|
||||
im_data = (im_data - minvalue) / (maxvalue - minvalue) * 254 + 1
|
||||
im_data = np.clip(im_data, 0, 255)
|
||||
|
||||
return im_data.astype(np.uint8)
|
||||
|
||||
def DataStrech(im_data,strechmethod):
|
||||
# [,"Linear1","Linear2","Linear5","SquareRoot"]
|
||||
if strechmethod == "Linear" :
|
||||
return Strech_linear(im_data)
|
||||
elif strechmethod == "Linear1":
|
||||
return Strech_linear1(im_data)
|
||||
elif strechmethod == "Linear2":
|
||||
return Strech_linear2(im_data)
|
||||
elif strechmethod == "Linear5":
|
||||
return Strech_linear5(im_data)
|
||||
elif strechmethod == "SquareRoot":
|
||||
return Strech_SquareRoot(im_data)
|
||||
else:
|
||||
return im_data.astype(np.uint8)
|
||||
|
||||
|
||||
|
||||
# 文件模式
|
||||
def stretchProcess(infilepath,outfilepath,strechmethod):
|
||||
im_proj, im_Geotrans, im_data=read_tif(infilepath)
|
||||
envifilepath=get_filename_without_ext(outfilepath)+".bin"
|
||||
envifilepath=os.path.join(os.path.dirname(outfilepath),envifilepath)
|
||||
im_data = DataStrech(im_data,strechmethod)
|
||||
im_data = im_data.astype(np.uint8)
|
||||
write_envi(im_data,im_Geotrans,im_proj,envifilepath)
|
||||
Image.fromarray(im_data).save(outfilepath,compress_level=0)
|
||||
print("图像拉伸处理结束")
|
||||
|
||||
|
||||
def getsliceGeotrans(GeoTransform,Xpixel,Ypixel):
|
||||
XGeo = GeoTransform[0]+GeoTransform[1]*Xpixel+GeoTransform[2]*Ypixel
|
||||
YGeo = GeoTransform[3]+GeoTransform[4]*Xpixel+GeoTransform[5]*Ypixel
|
||||
result=[
|
||||
XGeo,GeoTransform[1],GeoTransform[2],
|
||||
YGeo,GeoTransform[4],GeoTransform[5]
|
||||
]
|
||||
return result
|
||||
|
||||
|
||||
def is_all_same(lst):
|
||||
arr = np.array(lst)
|
||||
# arr_num=arr.size
|
||||
sum_data=np.sum(arr != arr[0])
|
||||
return sum_data<400
|
||||
|
||||
def getNextSliceNumber(n,sliceSize,overlap=0.25):
|
||||
step=int(sliceSize*(1-overlap))+1
|
||||
ti = list(range(0, n, step))
|
||||
newN= n if ti[-1]+1024 < n else ti[-1]+1024
|
||||
# 评价重叠率
|
||||
movelayer=[]
|
||||
for i in range(len(ti)-1):
|
||||
movelayer.append((ti[i] + 1024 - ti[i + 1]) / 1024 * 100.0)
|
||||
print("重叠率:",movelayer)
|
||||
return newN,ti
|
||||
|
||||
def sliceShipDataset(rootname,im_data,src_im_data, im_Geotrans, im_proj, outfolder):
|
||||
binfolder=os.path.join(outfolder,"舰船","unit8binfolder")
|
||||
pngfolder=os.path.join(outfolder,"舰船","pngfolder")
|
||||
tifffolder=os.path.join(outfolder,"舰船","tifffolder")
|
||||
|
||||
|
||||
h,w=im_data.shape
|
||||
nextH,ht=getNextSliceNumber(h,shipsliceSize,BlockOverLayer)
|
||||
nextW,wt=getNextSliceNumber(w,shipsliceSize,BlockOverLayer)
|
||||
padH=nextH-h
|
||||
padW=nextW-w
|
||||
im_data=np.pad(im_data,((0,padH),(0,padW)),mode='constant',constant_values=0)
|
||||
src_im_data=np.pad(src_im_data,((0,padH),(0,padW)),mode='constant',constant_values=0)
|
||||
slice_ID=0
|
||||
for hi in ht:
|
||||
for wi in wt:
|
||||
geotrans_temp=getsliceGeotrans(im_Geotrans,wi,hi)
|
||||
im_data_temp=im_data[hi:hi+shipsliceSize,wi:wi+shipsliceSize]
|
||||
src_im_data_temp=src_im_data[hi:hi+shipsliceSize,wi:wi+shipsliceSize]
|
||||
slice_ID = slice_ID + 1
|
||||
if not is_all_same(im_data_temp):
|
||||
sliceBinPath=os.path.join(binfolder, rootname+"_"+str(slice_ID).zfill(4)+"_image.tiff")
|
||||
slicepngPath=os.path.join(pngfolder, rootname+"_"+str(slice_ID).zfill(4)+"_image.png")
|
||||
slicesrctiffPath=os.path.join(tifffolder, rootname+"_"+str(slice_ID).zfill(4)+"_image.tiff")
|
||||
|
||||
write_tiff(src_im_data_temp, geotrans_temp, im_proj, slicesrctiffPath)
|
||||
write_envi(im_data_temp,geotrans_temp,im_proj,sliceBinPath)
|
||||
Image.fromarray(im_data_temp).save(slicepngPath,compress_level=0)
|
||||
|
||||
print("图像切片结束")
|
||||
return slice_ID
|
||||
|
||||
|
||||
|
||||
def ishasPort(im_Geotrans,im_data,MLCPoints,JLCPoints,MJLCPoints):
|
||||
LCpoints=MLCPoints+JLCPoints+MJLCPoints
|
||||
# 获取范围
|
||||
rows=im_data.shape[0]
|
||||
cols=im_data.shape[1]
|
||||
x1=im_Geotrans[0]+im_Geotrans[1]*0
|
||||
x2=im_Geotrans[0]+im_Geotrans[1]*cols
|
||||
|
||||
y1=im_Geotrans[3]+im_Geotrans[5]*0
|
||||
y2=im_Geotrans[3]+im_Geotrans[5]*rows
|
||||
|
||||
xmin=min(x1,x2)
|
||||
xmax=max(x1,x2)
|
||||
ymin=min(y1,y2)
|
||||
ymax=max(y1,y2)
|
||||
# 数据处理
|
||||
for p in LCpoints:
|
||||
x_in_range = (p[0] >= xmin) & (p[0]<= xmax)
|
||||
y_in_range = (p[1] >= ymin) & (p[1] <= ymax)
|
||||
within_rect_indices_mask = x_in_range & y_in_range
|
||||
if within_rect_indices_mask:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
|
||||
|
||||
def slicePortDataset(rootname,im_data,src_im_data, im_Geotrans, im_proj, outfolder,slice_ID,portfilestr):
|
||||
# 读取portfilestr 中文件
|
||||
MLCPoints=[]
|
||||
JLCPoints=[]
|
||||
MJLCPoints=[]
|
||||
portfilelines=[]
|
||||
with open(portfilestr,"r",encoding="utf-8") as portfile:
|
||||
portfilelines=portfile.readlines()
|
||||
for line in portfilelines:
|
||||
if(len(line)>3):
|
||||
linemetas=line.split("\t\t")
|
||||
clsname=linemetas[0]
|
||||
pointstr=linemetas[1]
|
||||
pointx=float(pointstr.split(",")[0]) # PX
|
||||
pointy=float(pointstr.split(",")[1]) # Py
|
||||
if clsname=="JLC":
|
||||
JLCPoints.append([pointx,pointy])
|
||||
elif clsname=="MJLC":
|
||||
MJLCPoints.append([pointx,pointy])
|
||||
elif clsname=="MLC":
|
||||
MLCPoints.append([pointx,pointy])
|
||||
# 处理文件脚本
|
||||
if len(MLCPoints)==0 and len(JLCPoints)==0 and len(MJLCPoints)==0:
|
||||
return
|
||||
else:
|
||||
pass
|
||||
# 切片主流程
|
||||
binfolder=os.path.join(outfolder,"港口","unit8binfolder")
|
||||
pngfolder=os.path.join(outfolder,"港口","pngfolder")
|
||||
tifffolder=os.path.join(outfolder,"港口","tifffolder")
|
||||
|
||||
for P in JLCPoints:
|
||||
Px=P[0]
|
||||
Py=P[1]
|
||||
Sx=P[0]-portsliceSize/2
|
||||
Sy=P[1]-portsliceSize/2
|
||||
wi=Sx if Sx>0 else 0
|
||||
hi=Sy if Sy>0 else 0
|
||||
slice_ID = slice_ID + 1
|
||||
im_data_temp = im_data[hi:hi + portsliceSize, wi:wi + portsliceSize]
|
||||
src_im_data_temp = src_im_data[hi:hi + portsliceSize, wi:wi + portsliceSize]
|
||||
|
||||
sliceBinPath = os.path.join(binfolder, rootname + "_" + str(slice_ID).zfill(4) + "_image.tiff")
|
||||
slicepngPath = os.path.join(pngfolder, rootname + "_" + str(slice_ID).zfill(4) + "_image.png")
|
||||
slicesrctiffPath = os.path.join(tifffolder, rootname + "_" + str(slice_ID).zfill(4) + "_image.tiff")
|
||||
|
||||
geotrans_temp = getsliceGeotrans(im_Geotrans, wi, hi)
|
||||
write_tiff(src_im_data_temp, geotrans_temp, im_proj, slicesrctiffPath)
|
||||
write_envi(im_data_temp, geotrans_temp, im_proj, sliceBinPath)
|
||||
Image.fromarray(im_data_temp).save(slicepngPath, compress_level=4)
|
||||
|
||||
for P in MJLCPoints:
|
||||
Px = P[0]
|
||||
Py = P[1]
|
||||
Sx = P[0] - portsliceSize / 2
|
||||
Sy = P[1] - portsliceSize / 2
|
||||
wi = Sx if Sx > 0 else 0
|
||||
hi = Sy if Sy > 0 else 0
|
||||
slice_ID = slice_ID + 1
|
||||
im_data_temp = im_data[hi:hi + portsliceSize, wi:wi + portsliceSize]
|
||||
src_im_data_temp = src_im_data[hi:hi + portsliceSize, wi:wi + portsliceSize]
|
||||
|
||||
sliceBinPath = os.path.join(binfolder, rootname + "_" + str(slice_ID).zfill(4) + "_image.tiff")
|
||||
slicepngPath = os.path.join(pngfolder, rootname + "_" + str(slice_ID).zfill(4) + "_image.png")
|
||||
slicesrctiffPath = os.path.join(tifffolder, rootname + "_" + str(slice_ID).zfill(4) + "_image.tiff")
|
||||
|
||||
geotrans_temp = getsliceGeotrans(im_Geotrans, wi, hi)
|
||||
write_tiff(src_im_data_temp, geotrans_temp, im_proj, slicesrctiffPath)
|
||||
write_envi(im_data_temp, geotrans_temp, im_proj, sliceBinPath)
|
||||
Image.fromarray(im_data_temp).save(slicepngPath, compress_level=4)
|
||||
|
||||
for P in MLCPoints:
|
||||
Px = P[0]
|
||||
Py = P[1]
|
||||
Sx = P[0] - portsliceSize / 2
|
||||
Sy = P[1] - portsliceSize / 2
|
||||
wi = Sx if Sx > 0 else 0
|
||||
hi = Sy if Sy > 0 else 0
|
||||
slice_ID = slice_ID + 1
|
||||
im_data_temp = im_data[hi:hi + portsliceSize, wi:wi + portsliceSize]
|
||||
src_im_data_temp = src_im_data[hi:hi + portsliceSize, wi:wi + portsliceSize]
|
||||
|
||||
sliceBinPath = os.path.join(binfolder, rootname + "_" + str(slice_ID).zfill(4) + "_image.tiff")
|
||||
slicepngPath = os.path.join(pngfolder, rootname + "_" + str(slice_ID).zfill(4) + "_image.png")
|
||||
slicesrctiffPath = os.path.join(tifffolder, rootname + "_" + str(slice_ID).zfill(4) + "_image.tiff")
|
||||
|
||||
geotrans_temp = getsliceGeotrans(im_Geotrans, wi, hi)
|
||||
write_tiff(src_im_data_temp, geotrans_temp, im_proj, slicesrctiffPath)
|
||||
write_envi(im_data_temp, geotrans_temp, im_proj, sliceBinPath)
|
||||
Image.fromarray(im_data_temp).save(slicepngPath, compress_level=4)
|
||||
|
||||
print("图像切片结束")
|
||||
return slice_ID
|
||||
|
||||
def sliceLabelPortDataset(rootname,im_data,src_im_data, im_Geotrans, im_proj, outfolder,slice_ID,portfilestr):
|
||||
# 读取portfilestr 中文件
|
||||
MLCPoints=[]
|
||||
JLCPoints=[]
|
||||
MJLCPoints=[]
|
||||
with open(portfilestr,"r",encoding="utf-8") as portfile:
|
||||
for line in portfile.readlines():
|
||||
if(len(line)>3):
|
||||
linemetas=line.split("\t\t")
|
||||
clsname=linemetas[0]
|
||||
pointstr=linemetas[1]
|
||||
pointx=float(pointstr.split(",")[0])
|
||||
pointy=float(pointstr.split(",")[1])
|
||||
if clsname=="JLC":
|
||||
JLCPoints.append([pointx,pointy])
|
||||
elif clsname=="MJLC":
|
||||
MJLCPoints.append([pointx,pointy])
|
||||
elif clsname=="MLC":
|
||||
MLCPoints.append([pointx,pointy])
|
||||
# 处理文件脚本
|
||||
if len(MLCPoints)==0 and len(JLCPoints)==0 and len(MJLCPoints)==0:
|
||||
return
|
||||
else:
|
||||
pass
|
||||
# 切片主流程
|
||||
portuint8Tifffolder=os.path.join(outfolder,"港口","unit8tiff")
|
||||
portlabelfolder=os.path.join(outfolder,"港口","MLCLabels")
|
||||
unit8tiffPath=os.path.join(portuint8Tifffolder,"{}_uint8.tiff".format(rootname))
|
||||
uint8labelPath=os.path.join(portlabelfolder,"{}_uint8.csv".format(rootname))
|
||||
write_envi(im_data,im_Geotrans,im_proj,unit8tiffPath)
|
||||
with open(portfilestr,"r",encoding="utf-8") as portfile:
|
||||
with open(uint8labelPath, "w", encoding="utf-8") as labelfile:
|
||||
for line in portfile.readlines():
|
||||
if (len(line) > 3):
|
||||
linemetas = line.split("\t\t")
|
||||
clsname = linemetas[0]
|
||||
pointstr = linemetas[1]
|
||||
pointx = float(pointstr.split(",")[0])
|
||||
pointy = float(pointstr.split(",")[1])
|
||||
labelfile.write("{},{},{}\n".format(pointx,pointy,clsname))
|
||||
|
||||
return None
|
||||
|
||||
|
||||
|
||||
|
||||
def stretchSliceProcess(infilepath, outfolder,portfilestr, strechmethod):
|
||||
shipbinfolder=os.path.join(outfolder,"舰船","unit8binfolder")
|
||||
shippngfolder=os.path.join(outfolder,"舰船","pngfolder")
|
||||
shiptifffolder=os.path.join(outfolder,"舰船","tifffolder")
|
||||
allpngfolder = os.path.join(outfolder, "allpngfolder")
|
||||
|
||||
portbinfolder=os.path.join(outfolder,"港口","unit8binfolder")
|
||||
portpngfolder=os.path.join(outfolder,"港口","pngfolder")
|
||||
porttifffolder=os.path.join(outfolder,"港口","tifffolder")
|
||||
|
||||
portuint8Tifffolder=os.path.join(outfolder,"港口","unit8tiff")
|
||||
portlabelfolder=os.path.join(outfolder,"港口","PortLabels")
|
||||
|
||||
existOrCreate(shipbinfolder)
|
||||
existOrCreate(shippngfolder)
|
||||
existOrCreate(shiptifffolder)
|
||||
existOrCreate(allpngfolder)
|
||||
existOrCreate(portbinfolder)
|
||||
existOrCreate(portpngfolder)
|
||||
existOrCreate(porttifffolder)
|
||||
existOrCreate(portuint8Tifffolder)
|
||||
existOrCreate(portlabelfolder)
|
||||
|
||||
|
||||
im_proj, im_Geotrans, im_data=read_tif(infilepath)
|
||||
src_im_data=im_data*1.0
|
||||
im_data = DataStrech(im_data,strechmethod) # 拉伸
|
||||
im_data = im_data.astype(np.uint8)
|
||||
rootname=Path(infilepath).stem
|
||||
allImagePath=os.path.join(allpngfolder, rootname+"_all.png")
|
||||
Image.fromarray(im_data).save(allImagePath,compress_level=9)
|
||||
# write_allExtend(im_data, im_Geotrans, im_proj, allImagePath)
|
||||
slice_ID=0
|
||||
slice_ID=sliceShipDataset(rootname,im_data, src_im_data,im_Geotrans, im_proj, outfolder) # 舰船切片
|
||||
slice_ID=slice_ID+1
|
||||
if os.path.exists(portfilestr):
|
||||
print("存在港口文件")
|
||||
slice_ID=slicePortDataset(rootname,im_data, src_im_data,im_Geotrans, im_proj, outfolder,slice_ID,portfilestr)
|
||||
# slice_ID=sliceLabelPortDataset(rootname,im_data, src_im_data,im_Geotrans, im_proj, outfolder,slice_ID,portfilestr) # 港口拉伸
|
||||
print("图像切片与拉伸完成")
|
||||
pass
|
||||
|
||||
|
||||
def getParams():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('-i','--infile',type=str,default=r"F:\天仪SAR卫星数据集\舰船数据\bc2-sp-org-vv-20250205t032055-021998-000036-0055ee-01.tiff", help='输入shapefile文件')
|
||||
parser.add_argument('-p', '--portfile',type=str,default=r"F:\天仪SAR卫星数据集\舰船数据\bc2-sp-org-vv-20250205t032055-021998-000036-0055ee-01.txt", help='输出geojson文件')
|
||||
parser.add_argument('-o', '--outfile',type=str,default=r"F:\天仪SAR卫星数据集\舰船数据\切片结果", help='输出geojson文件')
|
||||
group = parser.add_mutually_exclusive_group()
|
||||
group.add_argument(
|
||||
'--filemode',
|
||||
action='store_const',
|
||||
const='filemode',
|
||||
dest='mode',
|
||||
help='文件模式'
|
||||
)
|
||||
group.add_argument(
|
||||
'--slicemode',
|
||||
action='store_const',
|
||||
const='slicemode',
|
||||
dest='mode',
|
||||
help='切片模式'
|
||||
)
|
||||
parser.set_defaults(mode='slicemode')
|
||||
group = parser.add_mutually_exclusive_group()
|
||||
group.add_argument(
|
||||
'--Linear',
|
||||
action='store_const',
|
||||
const='Linear',
|
||||
dest='method',
|
||||
help='线性拉伸'
|
||||
)
|
||||
group.add_argument(
|
||||
'--Linear1prec',
|
||||
action='store_const',
|
||||
const='Linear1',
|
||||
dest='method',
|
||||
help='1%线性拉伸'
|
||||
)
|
||||
group.add_argument(
|
||||
'--Linear2prec',
|
||||
action='store_const',
|
||||
const='Linear2',
|
||||
dest='method',
|
||||
help='2%线性拉伸'
|
||||
)
|
||||
group.add_argument(
|
||||
'--Linear5prec',
|
||||
action='store_const',
|
||||
const='Linear5',
|
||||
dest='method',
|
||||
help='5%线性拉伸'
|
||||
)
|
||||
group.add_argument(
|
||||
'--SquareRoot',
|
||||
action='store_const',
|
||||
const='SquareRoot',
|
||||
dest='method',
|
||||
help='平方根拉伸'
|
||||
)
|
||||
parser.set_defaults(method='SquareRoot')
|
||||
|
||||
args = parser.parse_args()
|
||||
return args
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
parser = getParams()
|
||||
intiffPath=parser.infile
|
||||
modestr=parser.mode
|
||||
methodstr = parser.method
|
||||
|
||||
if modestr == "filemode":
|
||||
outbinPath = parser.outfile
|
||||
print('infile=', intiffPath)
|
||||
print('outfile=', outbinPath)
|
||||
print('method=', methodstr)
|
||||
stretchProcess(intiffPath, outbinPath, methodstr)
|
||||
elif modestr == "slicemode":
|
||||
outfolder = parser.outfile
|
||||
portfilestr = parser.portfile
|
||||
print('infile=', intiffPath)
|
||||
print('outfolder=', outfolder)
|
||||
print('method=', methodstr)
|
||||
print('portfile=', portfilestr)
|
||||
stretchSliceProcess(intiffPath, outfolder,portfilestr, methodstr)
|
||||
pass
|
||||
else:
|
||||
print("模式错误")
|
||||
exit(2)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
exit(3)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,301 +0,0 @@
|
|||
from osgeo import ogr
|
||||
import os
|
||||
import argparse
|
||||
from osgeo import ogr, gdal
|
||||
import os
|
||||
import argparse
|
||||
import numpy as np
|
||||
from scipy.spatial import KDTree
|
||||
from tools.DotaOperator import DotaObj,readDotaFile,writerDotaFile,createDota
|
||||
from glob import glob
|
||||
from pathlib import Path
|
||||
import shutil
|
||||
|
||||
"""
|
||||
1. 港口,5000x5000,军港与民港切片,
|
||||
a. 预标注框给他们
|
||||
b. 重叠率25%重复
|
||||
c. 军民2000m 以内,影像抽出来
|
||||
d. 原影像如果只有 1 个港口,-》 港口类型
|
||||
多 个港口,-》 远近,如果港口距离1000m ,单独拉出来
|
||||
|
||||
"""
|
||||
|
||||
|
||||
MLCName="MLC" # M
|
||||
JLCName="JLC" # J
|
||||
MJLCName="MJLC" # JM 混合
|
||||
NOLCName="NOLC" # 没有港口
|
||||
|
||||
def find_tif_files_pathlib(directory):
|
||||
path = Path(directory)
|
||||
# 使用rglob递归匹配所有.tif和.tiff文件
|
||||
tif_files = list(path.rglob('*.tiff'))+list(path.rglob('*.tif'))
|
||||
# 将Path对象转换为字符串路径
|
||||
return [str(file) for file in tif_files]
|
||||
|
||||
|
||||
def find_srcPath(srcFolder):
|
||||
root_path = Path(srcFolder)
|
||||
target_path = [folderpath for folderpath in root_path.rglob("*") if folderpath.is_dir() and folderpath.name=="0-原图"]
|
||||
tiff_files = []
|
||||
for folderpath in target_path:
|
||||
tiff_files=tiff_files+find_tif_files_pathlib(folderpath)
|
||||
|
||||
tiff_dict={}
|
||||
for filepath in tiff_files:
|
||||
rootname=Path(filepath).stem
|
||||
tiff_dict[rootname]=filepath
|
||||
|
||||
return tiff_dict
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def read_tifInfo(path):
|
||||
dataset = gdal.Open(path) # 打开TIF文件
|
||||
if dataset is None:
|
||||
print("无法打开文件,读取文件信息")
|
||||
return None, None, None
|
||||
|
||||
cols = dataset.RasterXSize # 图像宽度
|
||||
rows = dataset.RasterYSize # 图像高度
|
||||
bands = dataset.RasterCount
|
||||
im_proj = dataset.GetProjection() # 获取投影信息
|
||||
im_Geotrans = dataset.GetGeoTransform() # 获取仿射变换信息
|
||||
# im_data = dataset.ReadAsArray(0, 0, cols, rows) # 读取栅格数据为NumPy数组
|
||||
print("行数:", rows)
|
||||
print("列数:", cols)
|
||||
print("波段:", bands)
|
||||
x1=im_Geotrans[0]+im_Geotrans[1]*0
|
||||
x2=im_Geotrans[0]+im_Geotrans[1]*cols
|
||||
|
||||
y1=im_Geotrans[3]+im_Geotrans[5]*0
|
||||
y2=im_Geotrans[3]+im_Geotrans[5]*rows
|
||||
|
||||
xmin=min(x1,x2)
|
||||
xmax=max(x1,x2)
|
||||
ymin=min(y1,y2)
|
||||
ymax=max(y1,y2)
|
||||
|
||||
geoExtend=[xmin,ymin,xmax,ymax]
|
||||
del dataset # 关闭数据集
|
||||
return im_proj, im_Geotrans,geoExtend
|
||||
|
||||
def getshapefileInfo(shp_path):
|
||||
"""
|
||||
将Shapefile转换为DOTA格式
|
||||
:param shp_path: Shapefile文件路径
|
||||
"""
|
||||
|
||||
geom_points=[]
|
||||
|
||||
print("shapefile: ",shp_path)
|
||||
|
||||
# 注册所有驱动
|
||||
ogr.RegisterAll()
|
||||
|
||||
# 打开Shapefile文件
|
||||
driver = ogr.GetDriverByName('ESRI Shapefile')
|
||||
datasource = driver.Open(shp_path, 0)
|
||||
if datasource is None:
|
||||
print("无法打开Shapefile文件")
|
||||
return
|
||||
|
||||
print("layer count: ",datasource.GetLayerCount())
|
||||
for layerid in range(datasource.GetLayerCount()):
|
||||
print("layer id: ",layerid)
|
||||
# 获取图层
|
||||
layer = datasource.GetLayer(layerid)
|
||||
layer_defn=layer.GetLayerDefn()
|
||||
field_count=layer_defn.GetFieldCount()
|
||||
|
||||
print("field_count:", field_count)
|
||||
for i in range (field_count):
|
||||
field_defn=layer_defn.GetFieldDefn(i)
|
||||
field_name=field_defn.GetName()
|
||||
field_type=field_defn.GetType()
|
||||
field_type_name=field_defn.GetFieldTypeName(field_type)
|
||||
print("field_name:", field_name, field_type_name, field_type_name)
|
||||
|
||||
for feature in layer:
|
||||
geom = feature.GetGeometryRef()
|
||||
if geom.GetGeometryName() == 'POINT':
|
||||
x=geom.GetX()
|
||||
y=geom.GetY()
|
||||
geom_points.append([x,y])
|
||||
return np.array(geom_points)
|
||||
|
||||
|
||||
def getTiffsInfo(tiffnames,folderpath):
|
||||
"""
|
||||
获取所有影像的几何信息
|
||||
Args:
|
||||
tiff_paths: tiff列表
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
tiffdict={}
|
||||
for tiff_name in tiffnames:
|
||||
if tiff_name.endswith(".tiff"):
|
||||
tiff_path=os.path.join(folderpath,tiff_name)
|
||||
im_proj, im_Geotrans, geoExtend=read_tifInfo(tiff_path)
|
||||
tiffdict[tiff_name]={"geoExtend":geoExtend,"geoTrans":im_Geotrans,"imProj":im_proj}
|
||||
return tiffdict
|
||||
|
||||
|
||||
def getMJSignal(tiffpath,shipPortTree,outfolderPath):
|
||||
rootname=Path(tiffpath).stem
|
||||
portTxtpath=os.path.join(outfolderPath,rootname+".txt")
|
||||
im_proj, im_Geotrans, geoExtend = read_tifInfo(tiffpath) # geoExtend : [xmin,ymin,xmax,ymax]
|
||||
[xmin, ymin, xmax, ymax]=geoExtend
|
||||
center_x = (xmin + xmax) / 2.0
|
||||
center_y = (ymin + ymax) / 2.0
|
||||
center_point = [center_x, center_y]
|
||||
# 2. 计算能够覆盖整个矩形区域的最小半径(中心点到任一角点的最大距离)
|
||||
radius_to_corner = np.sqrt((xmax - center_x) ** 2 + (ymax - center_y) ** 2)
|
||||
|
||||
MLCFlag=False
|
||||
JLCFlag=False
|
||||
## MLC
|
||||
if MLCName in shipPortTree and not shipPortTree[MLCName] is None:
|
||||
# 3. 使用 query_ball_point 查找以中心点为圆心,radius_to_corner 为半径的圆内的所有点的索引
|
||||
potential_indices = shipPortTree[MLCName].query_ball_point(center_point, r=radius_to_corner)
|
||||
|
||||
# 4. 获取这些潜在点的实际坐标
|
||||
# 假设你的 KDTree 是从 data_points 构建的:MLCTree = KDTree(data_points)
|
||||
potential_points = shipPortTree[MLCName].data[potential_indices] # 这是所有潜在点的坐标数组
|
||||
|
||||
# 5. 进行精确的矩形范围过滤
|
||||
# 条件判断:x 坐标在 xmin 和 xmax 之间,且 y 坐标在 ymin 和 ymax 之间
|
||||
x_in_range = (potential_points[:, 0] >= xmin) & (potential_points[:, 0] <= xmax)
|
||||
y_in_range = (potential_points[:, 1] >= ymin) & (potential_points[:, 1] <= ymax)
|
||||
within_rect_indices_mask = x_in_range & y_in_range
|
||||
|
||||
# 6. 获取最终在矩形范围内的点的坐标(在原始 data_points 中的索引是 potential_indices[within_rect_indices_mask])
|
||||
final_points = potential_points[within_rect_indices_mask]
|
||||
|
||||
# final_points 就是你要的矩形范围内的点
|
||||
# 如果你需要的是这些点在原始数据中的索引,而不是坐标本身:
|
||||
final_indices = np.array(potential_indices)[within_rect_indices_mask]
|
||||
if final_points.shape[0]>0:
|
||||
MLCFlag=True
|
||||
with open(portTxtpath,"w",encoding="utf-8") as f:
|
||||
for i in range(final_points.shape[0]):
|
||||
f.write("{}\t\t{},{}\n".format("MLC",final_points[i,0],final_points[i,1]))
|
||||
pass
|
||||
if JLCName in shipPortTree and not shipPortTree[JLCName] is None:
|
||||
# 3. 使用 query_ball_point 查找以中心点为圆心,radius_to_corner 为半径的圆内的所有点的索引
|
||||
potential_indices = shipPortTree[JLCName].query_ball_point(center_point, r=radius_to_corner)
|
||||
|
||||
# 4. 获取这些潜在点的实际坐标
|
||||
# 假设你的 KDTree 是从 data_points 构建的:MLCTree = KDTree(data_points)
|
||||
potential_points = shipPortTree[JLCName].data[potential_indices] # 这是所有潜在点的坐标数组
|
||||
|
||||
# 5. 进行精确的矩形范围过滤
|
||||
# 条件判断:x 坐标在 xmin 和 xmax 之间,且 y 坐标在 ymin 和 ymax 之间
|
||||
x_in_range = (potential_points[:, 0] >= xmin) & (potential_points[:, 0] <= xmax)
|
||||
y_in_range = (potential_points[:, 1] >= ymin) & (potential_points[:, 1] <= ymax)
|
||||
within_rect_indices_mask = x_in_range & y_in_range
|
||||
|
||||
# 6. 获取最终在矩形范围内的点的坐标(在原始 data_points 中的索引是 potential_indices[within_rect_indices_mask])
|
||||
final_points = potential_points[within_rect_indices_mask]
|
||||
|
||||
# final_points 就是你要的矩形范围内的点
|
||||
# 如果你需要的是这些点在原始数据中的索引,而不是坐标本身:
|
||||
final_indices = np.array(potential_indices)[within_rect_indices_mask]
|
||||
if final_points.shape[0]>0:
|
||||
JLCFlag=True
|
||||
with open(portTxtpath,"a",encoding="utf-8") as f:
|
||||
for i in range(final_points.shape[0]):
|
||||
f.write("{}\t\t{},{}\n".format("JLC",final_points[i,0],final_points[i,1]))
|
||||
pass
|
||||
# 处理软件
|
||||
return MLCFlag,JLCFlag
|
||||
|
||||
|
||||
|
||||
|
||||
def getTiffInPort(shipPortTree,srcFolderPath_0img,outTiffInfoFilePath,outfolderPath):
|
||||
tiffpaths=find_tif_files_pathlib(srcFolderPath_0img)
|
||||
tiffLCPort={
|
||||
MLCName:[],
|
||||
JLCName:[],
|
||||
MJLCName:[],
|
||||
NOLCName:[]
|
||||
}
|
||||
for tiffpath in tiffpaths:
|
||||
MLCFlag,JLCFlag=getMJSignal(tiffpath,shipPortTree,outfolderPath)
|
||||
|
||||
if MLCFlag and JLCFlag:
|
||||
tiffLCPort[MJLCName].append(tiffpath)
|
||||
elif MLCFlag:
|
||||
tiffLCPort[MLCName].append(tiffpath)
|
||||
elif JLCFlag:
|
||||
tiffLCPort[JLCName].append(tiffpath)
|
||||
else:
|
||||
tiffLCPort[NOLCName].append(tiffpath)
|
||||
|
||||
# 输出文件
|
||||
with open(outTiffInfoFilePath,'w',encoding="utf-8") as f:
|
||||
for k in tiffLCPort:
|
||||
for tiffpath in tiffLCPort[k]:
|
||||
f.write("{}\t\t{}\n".format(k,tiffpath))
|
||||
|
||||
|
||||
def SpliteProcess(srcfolderpath,outfolderPath,outfilepath,MLCPath,JLCPath,JMLCPath):
|
||||
shipPort={
|
||||
MLCName:getshapefileInfo(MLCPath),
|
||||
JLCName:getshapefileInfo(JLCPath),
|
||||
# "JMLC":getshapefileInfo(JMLCPath), # 舰船不区分 居民一体
|
||||
}
|
||||
|
||||
shipPortTree={
|
||||
MLCName:KDTree(shipPort[MLCName]),
|
||||
JLCName:KDTree(shipPort[JLCName]),
|
||||
# "JMLC":KDTree(shipPort["JMLC"]),
|
||||
}
|
||||
srcFolderPath_0img=os.path.join(srcfolderpath) # 0-原图 文件路径
|
||||
getTiffInPort(shipPortTree, srcFolderPath_0img, outfilepath,outfolderPath)
|
||||
return True
|
||||
pass
|
||||
|
||||
|
||||
def getParams():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('-s','--srcfolder',type=str,default=r'R:\TYSAR-德清院\TYSAR-条带模式(SM)\港口\20250903-不分类', help='输入shapefile文件')
|
||||
parser.add_argument('-o', '--outfilepath',type=str,default=r'D:\TYSAR-德清院\TYSAR-条带模式(SM)\港口\20250903-不分类\A-预处理\JMPort.txt', help='输出geojson文件')
|
||||
parser.add_argument('-f', '--folderOutpath',type=str,help=r'PortfolderOutpath', default=r'D:\TYSAR-德清院\TYSAR-条带模式(SM)\港口\20250903-不分类\A-预处理\PortPoints')
|
||||
parser.add_argument('-m', '--mLC',type=str,help=r'MLC', default=r'D:\TYSAR-德清院\目标点位信息更新\0828目标点位\港口(民船).shp')
|
||||
parser.add_argument('-j', '--jLC',type=str,help=r'JLC' ,default=r'D:\TYSAR-德清院\目标点位信息更新\0828目标点位\军港.shp')
|
||||
parser.add_argument('-jm', '--jmlc',type=str,help=r'JMLC', default=r'D:\TYSAR-德清院\目标点位信息更新\0828目标点位\军民一体港口.shp')
|
||||
args = parser.parse_args()
|
||||
return args
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
parser = getParams()
|
||||
srcfolder=parser.srcfolder
|
||||
outfilepath=parser.outfilepath
|
||||
folderOutpath=parser.folderOutpath
|
||||
mLCPath=parser.mLC
|
||||
jLCPath=parser.jLC
|
||||
jmLCPath=parser.jmlc
|
||||
print('srcfolder=',srcfolder)
|
||||
print('outfile=',outfilepath)
|
||||
print('outfolder=',folderOutpath)
|
||||
print('mLCPath=',mLCPath)
|
||||
print('jLCPath=',jLCPath)
|
||||
print('jmLCPath=',jmLCPath)
|
||||
SpliteProcess(srcfolder,folderOutpath,outfilepath,mLCPath,jLCPath,jmLCPath)
|
||||
exit(2)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
exit(3)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -1 +0,0 @@
|
|||
d:\ProgramData\anaconda3\envs\spacetySliceEnv\python.exe "R:\TYSAR-德清院\A-预处理-未标注\A0-算法版本\AA\SpacetySliceDataTools\generatorRasterSlicesTools\SplitShipPortRasterTools_AC.py" -s "R:\TYSAR-德清院\TYSAR-条带模式(SM)\航道\20250930-不分类\0-原图" -o "R:\TYSAR-德清院\TYSAR-条带模式(SM)\航道\20250930-不分类\A-预处理\AC-图像预处理\sumMJPort.txt" -f "R:\TYSAR-德清院\TYSAR-条带模式(SM)\航道\20250930-不分类\A-预处理\AC-图像预处理\sumMJPortFolder" -m "D:\TYSAR-德清院\目标点位信息更新\0828目标点位\港口(民船).shp" -j "D:\TYSAR-德清院\目标点位信息更新\0828目标点位\军港.shp" -jm "D:\TYSAR-德清院\目标点位信息更新\0828目标点位\军民一体港口.shp"
|
||||
|
|
@ -1,407 +0,0 @@
|
|||
"""
|
||||
|
||||
2025.09.16 切片增加后缀 _image.png _image.tiff
|
||||
2025.09.22 增加港口切片要求
|
||||
|
||||
"""
|
||||
from osgeo import ogr, gdal
|
||||
import os
|
||||
import argparse
|
||||
import numpy as np
|
||||
from PIL import Image
|
||||
import math
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
|
||||
sliceSize=1024
|
||||
BlockOverLayer=0.25
|
||||
|
||||
def get_filename_without_ext(path):
|
||||
base_name = os.path.basename(path)
|
||||
if '.' not in base_name or base_name.startswith('.'):
|
||||
return base_name
|
||||
return base_name.rsplit('.', 1)[0]
|
||||
|
||||
def read_tif(path):
|
||||
dataset = gdal.Open(path) # 打开TIF文件
|
||||
if dataset is None:
|
||||
print("无法打开文件")
|
||||
return None, None, None
|
||||
|
||||
cols = dataset.RasterXSize # 图像宽度
|
||||
rows = dataset.RasterYSize # 图像高度
|
||||
bands = dataset.RasterCount
|
||||
im_proj = dataset.GetProjection() # 获取投影信息
|
||||
im_Geotrans = dataset.GetGeoTransform() # 获取仿射变换信息
|
||||
im_data = dataset.ReadAsArray(0, 0, cols, rows) # 读取栅格数据为NumPy数组
|
||||
print("行数:", rows)
|
||||
print("列数:", cols)
|
||||
print("波段:", bands)
|
||||
del dataset # 关闭数据集
|
||||
return im_proj, im_Geotrans, im_data
|
||||
|
||||
def write_envi(im_data, im_geotrans, im_proj, output_path):
|
||||
"""
|
||||
将数组数据写入ENVI格式文件
|
||||
:param im_data: 输入的numpy数组(2D或3D)
|
||||
:param im_geotrans: 仿射变换参数(6元组)
|
||||
:param im_proj: 投影信息(WKT字符串)
|
||||
:param output_path: 输出文件路径(无需扩展名,会自动生成.dat和.hdr)
|
||||
"""
|
||||
im_bands = 1
|
||||
im_height, im_width = im_data.shape
|
||||
# 创建ENVI格式驱动
|
||||
driver = gdal.GetDriverByName("GTiff")
|
||||
dataset = driver.Create(output_path, im_width, im_height, 1, gdal.GDT_Byte)
|
||||
|
||||
if dataset is not None:
|
||||
dataset.SetGeoTransform(im_geotrans) # 设置地理变换参数
|
||||
dataset.SetProjection(im_proj) # 设置投影
|
||||
|
||||
dataset.GetRasterBand(1).WriteArray(im_data)
|
||||
|
||||
dataset.FlushCache() # 确保数据写入磁盘
|
||||
dataset = None # 关闭文件
|
||||
|
||||
|
||||
def write_tiff(im_data, im_geotrans, im_proj, output_path):
|
||||
"""
|
||||
将数组数据写入ENVI格式文件
|
||||
:param im_data: 输入的numpy数组(2D或3D)
|
||||
:param im_geotrans: 仿射变换参数(6元组)
|
||||
:param im_proj: 投影信息(WKT字符串)
|
||||
:param output_path: 输出文件路径(无需扩展名,会自动生成.dat和.hdr)
|
||||
"""
|
||||
im_bands = 1
|
||||
im_height, im_width = im_data.shape
|
||||
# 创建ENVI格式驱动
|
||||
driver = gdal.GetDriverByName("GTiff")
|
||||
dataset = driver.Create(output_path, im_width, im_height, 1, gdal.GDT_Float32)
|
||||
|
||||
if dataset is not None:
|
||||
dataset.SetGeoTransform(im_geotrans) # 设置地理变换参数
|
||||
dataset.SetProjection(im_proj) # 设置投影
|
||||
|
||||
dataset.GetRasterBand(1).WriteArray(im_data)
|
||||
|
||||
dataset.FlushCache() # 确保数据写入磁盘
|
||||
dataset = None # 关闭文件
|
||||
|
||||
|
||||
def Strech_linear(im_data):
|
||||
im_data_dB=10*np.log10(im_data)
|
||||
immask=np.isfinite(im_data_dB)
|
||||
infmask = np.isinf(im_data_dB)
|
||||
imvail_data=im_data[immask]
|
||||
im_data_dB=0
|
||||
|
||||
minvalue=np.nanmin(imvail_data)
|
||||
maxvalue=np.nanmax(imvail_data)
|
||||
|
||||
infmask = np.isinf(im_data_dB)
|
||||
im_data[infmask] = minvalue-100
|
||||
im_data = (im_data - minvalue) / (maxvalue - minvalue) * 254+1
|
||||
im_data=np.clip(im_data,0,255)
|
||||
return im_data.astype(np.uint8)
|
||||
|
||||
def Strech_linear1(im_data):
|
||||
im_data_dB = 10 * np.log10(im_data)
|
||||
immask = np.isfinite(im_data_dB)
|
||||
infmask = np.isinf(im_data_dB)
|
||||
imvail_data = im_data[immask]
|
||||
im_data_dB=0
|
||||
|
||||
minvalue=np.percentile(imvail_data,1)
|
||||
maxvalue = np.percentile(imvail_data, 99)
|
||||
|
||||
|
||||
im_data[infmask] = minvalue - 100
|
||||
im_data = (im_data - minvalue) / (maxvalue - minvalue) * 254 + 1
|
||||
im_data = np.clip(im_data, 0, 255)
|
||||
|
||||
return im_data.astype(np.uint8)
|
||||
|
||||
|
||||
def Strech_linear2(im_data):
|
||||
im_data_dB = 10 * np.log10(im_data)
|
||||
immask = np.isfinite(im_data_dB)
|
||||
infmask = np.isinf(im_data_dB)
|
||||
imvail_data = im_data[immask]
|
||||
im_data_dB = 0
|
||||
|
||||
minvalue = np.percentile(imvail_data, 2)
|
||||
maxvalue = np.percentile(imvail_data, 98)
|
||||
|
||||
im_data[infmask] = minvalue - 100
|
||||
im_data = (im_data - minvalue) / (maxvalue - minvalue) * 254 + 1
|
||||
im_data = np.clip(im_data, 0, 255)
|
||||
|
||||
return im_data.astype(np.uint8)
|
||||
|
||||
def Strech_linear5(im_data):
|
||||
im_data_dB = 10 * np.log10(im_data)
|
||||
immask = np.isfinite(im_data_dB)
|
||||
infmask = np.isinf(im_data_dB)
|
||||
imvail_data = im_data[immask]
|
||||
im_data_dB = 0
|
||||
|
||||
minvalue = np.percentile(imvail_data, 5)
|
||||
maxvalue = np.percentile(imvail_data, 95)
|
||||
|
||||
im_data[infmask] = minvalue - 100
|
||||
im_data = (im_data - minvalue) / (maxvalue - minvalue) * 254 + 1
|
||||
im_data = np.clip(im_data, 0, 255)
|
||||
|
||||
return im_data.astype(np.uint8)
|
||||
|
||||
def Strech_SquareRoot(im_data):
|
||||
# 判断是否为dB
|
||||
# immask = np.isfinite(im_data)
|
||||
# imvail_data = im_data[immask]
|
||||
# minvalue = np.percentile(imvail_data,30)
|
||||
# if minvalue<0 :
|
||||
# im_data=np.power(10.0,im_data/10.0)
|
||||
|
||||
im_data=np.sqrt(im_data)
|
||||
immask = np.isfinite(im_data)
|
||||
imvail_data = im_data[immask]
|
||||
|
||||
minvalue=np.nanmin(imvail_data)
|
||||
maxvalue=np.nanmax(imvail_data)
|
||||
minvalue_01Prec = np.percentile(imvail_data, 2) # 20250904 1%拉伸
|
||||
maxvalue_999Prec = np.percentile(imvail_data, 98)
|
||||
print('sqrt root min - max ', minvalue,maxvalue)
|
||||
if (maxvalue-minvalue)/(maxvalue_999Prec-minvalue_01Prec)>3: # 表示 拉伸之后,像素值绝大部分很有可能集中在 80
|
||||
minvalue=minvalue_01Prec
|
||||
maxvalue=maxvalue_999Prec
|
||||
print('sqrt root min(0.1) - max(99.9) ', minvalue, maxvalue)
|
||||
|
||||
|
||||
im_data = (im_data - minvalue) / (maxvalue - minvalue) * 254 + 1
|
||||
im_data = np.clip(im_data, 0, 255)
|
||||
|
||||
return im_data.astype(np.uint8)
|
||||
|
||||
def DataStrech(im_data,strechmethod):
|
||||
# [,"Linear1","Linear2","Linear5","SquareRoot"]
|
||||
if strechmethod == "Linear" :
|
||||
return Strech_linear(im_data)
|
||||
elif strechmethod == "Linear1":
|
||||
return Strech_linear1(im_data)
|
||||
elif strechmethod == "Linear2":
|
||||
return Strech_linear2(im_data)
|
||||
elif strechmethod == "Linear5":
|
||||
return Strech_linear5(im_data)
|
||||
elif strechmethod == "SquareRoot":
|
||||
return Strech_SquareRoot(im_data)
|
||||
else:
|
||||
return im_data.astype(np.uint8)
|
||||
|
||||
|
||||
|
||||
# 文件模式
|
||||
def stretchProcess(infilepath,outfilepath,strechmethod):
|
||||
im_proj, im_Geotrans, im_data=read_tif(infilepath)
|
||||
envifilepath=get_filename_without_ext(outfilepath)+".bin"
|
||||
envifilepath=os.path.join(os.path.dirname(outfilepath),envifilepath)
|
||||
im_data = DataStrech(im_data,strechmethod)
|
||||
im_data = im_data.astype(np.uint8)
|
||||
write_envi(im_data,im_Geotrans,im_proj,envifilepath)
|
||||
Image.fromarray(im_data).save(outfilepath,compress_level=0)
|
||||
print("图像拉伸处理结束")
|
||||
|
||||
|
||||
#切片模式
|
||||
def getSlicePoints(h):
|
||||
n = int(math.floor((h - 1024) * 1.2 / sliceSize))
|
||||
step=int(math.ceil((h-1024)/n))
|
||||
ti=list(range(0,h-1024,step))
|
||||
ti.append(h-1024)
|
||||
# 评价重叠率
|
||||
movelayer=[]
|
||||
for i in range(len(ti)-1):
|
||||
movelayer.append((ti[i] + 1024 - ti[i + 1]) / 1024 * 100.0)
|
||||
print("重叠率:",movelayer)
|
||||
return ti
|
||||
|
||||
|
||||
def getsliceGeotrans(GeoTransform,Xpixel,Ypixel):
|
||||
XGeo = GeoTransform[0]+GeoTransform[1]*Xpixel+GeoTransform[2]*Ypixel
|
||||
YGeo = GeoTransform[3]+GeoTransform[4]*Xpixel+GeoTransform[5]*Ypixel
|
||||
result=[
|
||||
XGeo,GeoTransform[1],GeoTransform[2],
|
||||
YGeo,GeoTransform[4],GeoTransform[5]
|
||||
]
|
||||
return result
|
||||
|
||||
|
||||
def is_all_same(lst):
|
||||
arr = np.array(lst)
|
||||
# arr_num=arr.size
|
||||
sum_data=np.sum(arr != arr[0])
|
||||
return sum_data<400
|
||||
|
||||
def getNextSliceNumber(n,sliceSize,overlap=0.25):
|
||||
step=int(sliceSize*(1-overlap))+1
|
||||
ti = list(range(0, n, step))
|
||||
newN= n if ti[-1]+1024 < n else ti[-1]+1024
|
||||
# 评价重叠率
|
||||
movelayer=[]
|
||||
for i in range(len(ti)-1):
|
||||
movelayer.append((ti[i] + 1024 - ti[i + 1]) / 1024 * 100.0)
|
||||
print("重叠率:",movelayer)
|
||||
return newN,ti
|
||||
|
||||
def sliceDataset(rootname,im_data,src_im_data, im_Geotrans, im_proj, outfolder):
|
||||
binfolder=os.path.join(outfolder,"unit8binfolder")
|
||||
pngfolder=os.path.join(outfolder,"pngfolder")
|
||||
tifffolder=os.path.join(outfolder,"tifffolder")
|
||||
|
||||
|
||||
h,w=im_data.shape
|
||||
nextH,ht=getNextSliceNumber(h,sliceSize,BlockOverLayer)
|
||||
nextW,wt=getNextSliceNumber(w,sliceSize,BlockOverLayer)
|
||||
padH=nextH-h
|
||||
padW=nextW-w
|
||||
im_data=np.pad(im_data,((0,padH),(0,padW)),mode='constant',constant_values=0)
|
||||
src_im_data=np.pad(src_im_data,((0,padH),(0,padW)),mode='constant',constant_values=0)
|
||||
slice_ID=0
|
||||
for hi in ht:
|
||||
for wi in wt:
|
||||
geotrans_temp=getsliceGeotrans(im_Geotrans,wi,hi)
|
||||
im_data_temp=im_data[hi:hi+1024,wi:wi+1024]
|
||||
src_im_data_temp=src_im_data[hi:hi+1024,wi:wi+1024]
|
||||
slice_ID = slice_ID + 1
|
||||
if not is_all_same(im_data_temp):
|
||||
sliceBinPath=os.path.join(binfolder, rootname+"_"+str(slice_ID).zfill(4)+"_image.tiff")
|
||||
slicepngPath=os.path.join(pngfolder, rootname+"_"+str(slice_ID).zfill(4)+"_image.png")
|
||||
slicesrctiffPath=os.path.join(tifffolder, rootname+"_"+str(slice_ID).zfill(4)+"_image.tiff")
|
||||
|
||||
write_tiff(src_im_data_temp, geotrans_temp, im_proj, slicesrctiffPath)
|
||||
write_envi(im_data_temp,geotrans_temp,im_proj,sliceBinPath)
|
||||
Image.fromarray(im_data_temp).save(slicepngPath,compress_level=0)
|
||||
|
||||
print("图像切片结束")
|
||||
|
||||
|
||||
def stretchSliceProcess(infilepath, outfolder, strechmethod):
|
||||
binfolder=os.path.join(outfolder,"unit8binfolder")
|
||||
pngfolder=os.path.join(outfolder,"pngfolder")
|
||||
tifffolder=os.path.join(outfolder,"tifffolder")
|
||||
allpngfolder = os.path.join(outfolder, "allpngfolder")
|
||||
if not os.path.exists(binfolder):
|
||||
os.makedirs(binfolder)
|
||||
if not os.path.exists(pngfolder):
|
||||
os.makedirs(pngfolder)
|
||||
if not os.path.exists(tifffolder):
|
||||
os.makedirs(tifffolder)
|
||||
if not os.path.exists(allpngfolder):
|
||||
os.makedirs(allpngfolder)
|
||||
im_proj, im_Geotrans, im_data=read_tif(infilepath)
|
||||
src_im_data=im_data*1.0
|
||||
im_data = DataStrech(im_data,strechmethod) # 拉伸
|
||||
im_data = im_data.astype(np.uint8)
|
||||
rootname=Path(infilepath).stem
|
||||
allImagePath=os.path.join(allpngfolder, rootname+"_all.png")
|
||||
Image.fromarray(im_data).save(allImagePath,compress_level=0)
|
||||
sliceDataset(rootname,im_data, src_im_data,im_Geotrans, im_proj, outfolder)
|
||||
print("图像切片与拉伸完成")
|
||||
pass
|
||||
|
||||
|
||||
def getParams():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('-i','--infile',type=str,default=r"F:\天仪SAR卫星数据集\舰船数据\bc2-sp-org-vv-20250205t032055-021998-000036-0055ee-01.tiff", help='输入shapefile文件')
|
||||
# parser.add_argument('-o', '--outfile',type=str,default=r"F:\天仪SAR卫星数据集\舰船数据\bc2-sp-org-vv-20250205t032055-021998-000036-0055ee-01.png", help='输出geojson文件')
|
||||
parser.add_argument('-o', '--outfile',type=str,default=r"F:\天仪SAR卫星数据集\舰船数据\切片结果", help='输出geojson文件')
|
||||
group = parser.add_mutually_exclusive_group()
|
||||
group.add_argument(
|
||||
'--filemode',
|
||||
action='store_const',
|
||||
const='filemode',
|
||||
dest='mode',
|
||||
help='文件模式'
|
||||
)
|
||||
group.add_argument(
|
||||
'--slicemode',
|
||||
action='store_const',
|
||||
const='slicemode',
|
||||
dest='mode',
|
||||
help='切片模式'
|
||||
)
|
||||
parser.set_defaults(mode='slicemode')
|
||||
group = parser.add_mutually_exclusive_group()
|
||||
group.add_argument(
|
||||
'--Linear',
|
||||
action='store_const',
|
||||
const='Linear',
|
||||
dest='method',
|
||||
help='线性拉伸'
|
||||
)
|
||||
group.add_argument(
|
||||
'--Linear1prec',
|
||||
action='store_const',
|
||||
const='Linear1',
|
||||
dest='method',
|
||||
help='1%线性拉伸'
|
||||
)
|
||||
group.add_argument(
|
||||
'--Linear2prec',
|
||||
action='store_const',
|
||||
const='Linear2',
|
||||
dest='method',
|
||||
help='2%线性拉伸'
|
||||
)
|
||||
group.add_argument(
|
||||
'--Linear5prec',
|
||||
action='store_const',
|
||||
const='Linear5',
|
||||
dest='method',
|
||||
help='5%线性拉伸'
|
||||
)
|
||||
group.add_argument(
|
||||
'--SquareRoot',
|
||||
action='store_const',
|
||||
const='SquareRoot',
|
||||
dest='method',
|
||||
help='平方根拉伸'
|
||||
)
|
||||
parser.set_defaults(method='SquareRoot')
|
||||
|
||||
args = parser.parse_args()
|
||||
return args
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
parser = getParams()
|
||||
intiffPath=parser.infile
|
||||
modestr=parser.mode
|
||||
methodstr = parser.method
|
||||
if modestr == "filemode":
|
||||
outbinPath = parser.outfile
|
||||
print('infile=', intiffPath)
|
||||
print('outfile=', outbinPath)
|
||||
print('method=', methodstr)
|
||||
stretchProcess(intiffPath, outbinPath, methodstr)
|
||||
elif modestr == "slicemode":
|
||||
outfolder = parser.outfile
|
||||
print('infile=', intiffPath)
|
||||
print('outfolder=', outfolder)
|
||||
print('method=', methodstr)
|
||||
stretchSliceProcess(intiffPath, outfolder, methodstr)
|
||||
pass
|
||||
else:
|
||||
print("模式错误")
|
||||
exit(2)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
exit(3)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -6,14 +6,11 @@ import os
|
|||
import argparse
|
||||
import numpy as np
|
||||
from scipy.spatial import KDTree
|
||||
from tools.DotaOperator import DotaObj,readDotaFile,writerDotaFile,createDota
|
||||
from DotaOperator import DotaObj,readDotaFile,writerDotaFile,createDota
|
||||
from glob import glob
|
||||
from pathlib import Path
|
||||
import shutil
|
||||
|
||||
def existOrCreate(dirpath):
|
||||
if not os.path.exists(dirpath):
|
||||
os.makedirs(dirpath)
|
||||
|
||||
def find_tif_files_pathlib(directory):
|
||||
path = Path(directory)
|
||||
|
|
|
|||
Binary file not shown.
Loading…
Reference in New Issue