Python中numpy.ix_ 的用法

本文介绍如何使用numpy库的ix_函数对多维数组特定行和列进行批量赋值,对比了不同赋值方式的效果,并解释了只读访问的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

对多行多列同时赋值可使用numpy.ix_

import numpy as np
A=np.zeros((6,6))
print(A)

输出结果为:

array([[0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0.]])

现在对A的第3、4行,第1,2列同时赋值为6,做法是

A[np.ix_([2,3],[0,1])]=6
print(A)

输出结果为

array([[0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0.],
       [6., 6., 0., 0., 0., 0.],
       [6., 6., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0.]])

需要注意的是

A[[2,3]][:,[0,1]]
#这种方式只有 read-only access(即只读权限),无法对指定的位置赋值
#示例
import numpy as np
A=np.zeros((5,5))
A[[2,3]][:,[0,1]]=6
print(A)

输出结果为

array([[0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0.]])

可以看到A的值并未改变

import cv2 import numpy as np import math class CDomPho: def __init__(self): # 初始化所有参数 self.m_f = self.m_Pxz = self.m_k1 = self.m_k2 = self.m_p1 = self.m_p2 = 0.0 self.m_X0 = self.m_Y0 = 0.0 self.m_cols = self.m_rows = 0 self.m_aopX = self.m_aopY = self.m_aopZ = self.m_aopP = self.m_aopO = self.m_aopK = 0.0 self.m_rotM = np.zeros(9) self.m_ref = np.zeros(6) def POK2M(self, p, o, k, r): """计算旋转矩阵""" cosp = math.cos(p) cosw = math.cos(o) cosk = math.cos(k) sinp = math.sin(p) sinw = math.sin(o) sink = math.sin(k) r[0] = cosp * cosk - sinp * sinw * sink r[1] = -cosp * sink - sinp * sinw * cosk r[2] = -sinp * cosw r[3] = cosw * sink r[4] = cosw * cosk r[5] = -sinw r[6] = sinp * cosk + cosp * sinw * sink r[7] = -sinp * sink + cosp * sinw * cosk r[8] = cosp * cosw def SetPara(self, aopX, aopY, aopZ, aopP, aopO, aopK, f, pxz, cols, rows, k1, k2, p1, p2, X0, Y0): """设置相机参数""" self.m_rotM = np.zeros(9) self.POK2M(aopP, aopO, aopK, self.m_rotM) self.m_aopX, self.m_aopY, self.m_aopZ = aopX, aopY, aopZ self.m_aopP, self.m_aopO, self.m_aopK = aopP, aopO, aopK self.m_f, self.m_Pxz = f, pxz self.m_k1, self.m_k2, self.m_p1, self.m_p2 = k1, k2, p1, p2 self.m_X0, self.m_Y0 = X0, Y0 self.m_cols, self.m_rows = cols, rows # 计算参考参数 self.m_ref[0] = -(cols / 2) * pxz self.m_ref[1] = pxz self.m_ref[2] = 0 self.m_ref[3] = -(rows / 2) * pxz self.m_ref[4] = 0 self.m_ref[5] = -pxz def Scan2Pho(self, scX, scY): """扫描坐标转像平面坐标""" phoX = self.m_ref[0] + self.m_ref[1] * scX - self.m_ref[2] * scY phoY = self.m_ref[3] + self.m_ref[4] * scX - self.m_ref[5] * scY # 畸变校正 if abs(self.m_k1) > 1e-12: x, y = phoX, phoY r2 = x * x + y * y r4 = r2 * r2 dx = x * (self.m_k1 * r2 + self.m_k2 * r4) + self.m_p1 * (r2 + 2 * x * x) + 2 * self.m_p2 * x * y dy = y * (self.m_k1 * r2 + self.m_k2 * r4) + self.m_p2 * (r2 + 2 * y * y) + 2 * self.m_p1 * x * y phoX -= dx phoY -= dy return phoX, phoY def Pho2Scan(self, phoX, phoY): """像平面坐标转扫描坐标""" # 畸变校正(近似迭代) if abs(self.m_k1) > 1e-12: x, y = phoX, phoY r2 = x * x + y * y r4 = r2 * r2 dx0 = x * (self.m_k1 * r2 + self.m_k2 * r4) + self.m_p1 * (r2 + 2 * x * x) + 2 * self.m_p2 * x * y dy0 = y * (self.m_k1 * r2 + self.m_k2 * r4) + self.m_p2 * (r2 + 2 * y * y) + 2 * self.m_p1 * x * y x = phoX + dx0 y = phoY + dy0 r2 = x * x + y * y r4 = r2 * r2 dx = x * (self.m_k1 * r2 + self.m_k2 * r4) + self.m_p1 * (r2 + 2 * x * x) + 2 * self.m_p2 * x * y dy = y * (self.m_k1 * r2 + self.m_k2 * r4) + self.m_p2 * (r2 + 2 * y * y) + 2 * self.m_p1 * x * y phoX += dx phoY += dy # 坐标变换 phoX -= self.m_ref[0] phoY -= self.m_ref[3] tt = self.m_ref[1] * self.m_ref[5] - self.m_ref[2] * self.m_ref[4] scX = (self.m_ref[5] * phoX - self.m_ref[2] * phoY) / tt scY = -(-self.m_ref[4] * phoX + self.m_ref[1] * phoY) / tt return scX, scY def PhoZ2Grd(self, px, py, gz): """像平面坐标转地面坐标""" A = self.m_rotM[0] * px + self.m_rotM[1] * py - self.m_rotM[2] * self.m_f B = self.m_rotM[3] * px + self.m_rotM[4] * py - self.m_rotM[5] * self.m_f C = self.m_rotM[6] * px + self.m_rotM[7] * py - self.m_rotM[8] * self.m_f if abs(C) > 1e-12: N = (gz - self.m_aopZ) / C else: N = 0.0 gx = self.m_aopX + A * N gy = self.m_aopY + B * N return gx, gy def Grd2Pho_(self, gx, gy, gz): """地面坐标转像平面坐标""" dx = gx - self.m_aopX dy = gy - self.m_aopY dz = gz - self.m_aopZ denom = self.m_rotM[2] * dx + self.m_rotM[5] * dy + self.m_rotM[8] * dz fm = -self.m_f / denom if abs(denom) > 1e-12 else 0 px = (self.m_rotM[0] * dx + self.m_rotM[3] * dy + self.m_rotM[6] * dz) * fm py = (self.m_rotM[1] * dx + self.m_rotM[4] * dy + self.m_rotM[7] * dz) * fm return px, py def ImgZ2Grd(self, xyz): """图像坐标转地面坐标""" results = [] for i in range(0, len(xyz), 3): scX, scY, Z = xyz[i], xyz[i + 1], xyz[i + 2] phoX, phoY = self.Scan2Pho(scX, scY) gx, gy = self.PhoZ2Grd(phoX, phoY, Z) results.extend([gx, gy, Z]) return results def Grd2Img(self, gx, gy, gz): """地面坐标转图像坐标""" px, py = self.Grd2Pho_(gx, gy, gz) scX, scY = self.Pho2Scan(px, py) return scX, scY # 主程序 if __name__ == "__main__": # 读取参数文件 with open(r'D:\shuiwei\para.txt') as file: file.readline() # 跳过第一行 params = list(map(float, file.readline().split())) # 解析参数 aopX, aopY, aopZ, aopP, aopO, aopK = params[0:6] f, Pxz, k1, k2, p1, p2, X0, Y0 = params[6:14] # 读取原始影像 m_img = cv2.imread(r'D:\shuiwei\1.jpg') if m_img is None: raise FileNotFoundError("无法读取图像文件 ") rows, cols = m_img.shape[:2] dompho = CDomPho() dompho.SetPara(aopX, aopY, aopZ, aopP, aopO, aopK, f, Pxz, cols, rows, k1, k2, p1, p2, X0, Y0) # 四个角点坐标(扫描坐标)和地面高度 corPt = [0.0, 0.0, 64.3, cols, 0,64.3, 0, rows,64.3, cols, rows,64.3] # 计算地面坐标 grd_coords = dompho.ImgZ2Grd(corPt) # 计算地面范围 gxs = grd_coords[0::3] gys = grd_coords[1::3] mingx, maxgx = min(gxs), max(gxs) mingy, maxgy = min(gys), max(gys) dx = maxgx - mingx dy = maxgy - mingy # 创建正射影像 resolution = 0.5 # 地面分辨率(米/像素) domCols = int(dx / resolution) + 1 domRows = int(dy / resolution) + 1 domImg = np.zeros((domRows, domCols, 3), dtype=np.uint8) h = 64.3 # 地面高度 gy = mingy # 进度计数器 total_pixels = domRows * domCols processed = 0 for r in range(domRows): gx = mingx for c in range(domCols): # 地面坐标转图像坐标 ix, iy = dompho.Grd2Img(gx, gy, h) # 最近邻插值 i = int(ix + 0.5) j = int(iy + 0.5) # 检查边界 if 0 <= i < cols and 0 <= j < rows: # 注意坐标转换:OpenCV原点在左上角,扫描坐标系原点在左下角 domImg[r, c] = m_img[rows - 1 - j, i] gx += resolution processed += 1 # 显示进度 if processed % 10000 == 0: percent = processed / total_pixels * 100 print(f"处理进度: {percent:.2f}%") gy += resolution # 显示和保存结果 cv2.imshow('Orthophoto', domImg) cv2.waitKey(0) cv2.imwrite('orthophoto_result.jpg', domImg) print("正射影像生成完成!") 生成的图片显示方式,无法仔细观察,能不能做成可以旋转和缩放的,但是不能改变分辨率
最新发布
06-26
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值