解决OpenCV代码TypeError: only integer scalar arrays can be converted to a scalar index
问题排查与修复方案
错误根因
代码存在3个问题共同触发报错:
- 变量名冲突:开头定义块大小的变量
B=8,后续拆分LAB通道时执行L,A,B=cv2.split(Trans_Color),直接将B覆盖为了B通道的二维numpy数组。后续循环中执行row*B时,实际是整数乘数组得到数组,切片时传入数组作为索引直接触发类型错误。 - 数值类型不匹配:计算分块数量
blocksV、blocksH时使用Python3普通除法/得到的是浮点数,range()函数不支持接收浮点数作为参数。 - 隐藏问题:计算了对齐到8像素的图像高宽
h、w,但未对原始图像做裁剪,若原图高宽不是8的整数倍,后续分块处理会出现尺寸不匹配问题。
修复方案
调整要点
- 将块大小的变量名从
B改为BLOCK_SIZE,避免和LAB的B通道变量冲突 - 计算完
h、w后裁剪原始图像,保证后续处理的图像尺寸都是8的整数倍 - 分块数量计算改用整数除法
//,保证blocksV、blocksH为整数类型
修复后完整可运行代码如下:
import cv2 import numpy as np BLOCK_SIZE=8 # 块大小变量名修改,避免和B通道冲突 img1 = cv2.imread(r'C:\Users\Leith\Desktop\Test Images\Goldhill_Final.bmp') h,w=np.array(img1.shape[:2])/BLOCK_SIZE * BLOCK_SIZE h=int(h) w=int(w) # 新增:裁剪图像到对齐后的尺寸 img1 = img1[:h, :w] Trans_Color=cv2.cvtColor(img1, cv2.COLOR_BGR2LAB) Trans_Color=Trans_Color.astype(int) L,A,B=cv2.split(Trans_Color) Three_Channels=[Trans_Color[:,:,0],A,B] QY=np.array([[16,11,10,16,24,40,51,61], [12,12,14,19,26,48,60,55], [14,13,16,24,40,57,69,56], [14,17,22,29,51,87,80,62], [18,22,37,56,68,109,103,77], [24,35,55,64,81,104,113,92], [49,64,78,87,103,121,120,101], [72,92,95,98,112,100,103,99]]) QC=np.array([[17,18,24,47,99,99,99,99], [18,21,26,66,99,99,99,99], [24,26,56,99,99,99,99,99], [47,66,99,99,99,99,99,99], [99,99,99,99,99,99,99,99], [99,99,99,99,99,99,99,99], [99,99,99,99,99,99,99,99], [99,99,99,99,99,99,99,99]]) QF=99.0 if QF < 50 and QF > 1: scale = np.floor(5000/QF) elif QF < 100: scale = 200-2*QF else: print("Quality Factor must be in the range [1..99]") scale=scale/100.0 Q=[QY*scale,QC*scale,QC*scale] TransAll=[] TransAllQuant=[] for idx,channel in enumerate(Three_Channels): channelrows=channel.shape[0] channelcols=channel.shape[1] Trans = np.zeros((channelrows,channelcols), np.float32) TransQuant = np.zeros((channelrows,channelcols), np.float32) # 改用整数除法得到整数类型的分块数量 blocksV=channelrows//BLOCK_SIZE blocksH=channelcols//BLOCK_SIZE vis0 = np.zeros((channelrows,channelcols), np.float32) vis0[:channelrows, :channelcols] = channel vis0=vis0-128 for row in range(blocksV): for col in range(blocksH): # 块大小改用修改后的BLOCK_SIZE变量 currentblock = cv2.dct(vis0[row*BLOCK_SIZE:(row+1)*BLOCK_SIZE,col*BLOCK_SIZE:(col+1)*BLOCK_SIZE]) Trans[row*BLOCK_SIZE:(row+1)*BLOCK_SIZE,col*BLOCK_SIZE:(col+1)*BLOCK_SIZE]=currentblock TransQuant[row*BLOCK_SIZE:(row+1)*BLOCK_SIZE,col*BLOCK_SIZE:(col+1)*BLOCK_SIZE]=np.round(currentblock/Q[idx]) TransAll.append(Trans) TransAllQuant.append(TransQuant)
内容的提问来源于stack exchange,提问作者Leith Abed
相关产品推荐
相关产品推荐

