项目场景:Video-Swin-Transformer训练
星光不问路人,时间有回报。
在训练模型时,读取图片数据的维度不是三维的,图片数据通道数正常是3,但训练时候,通道数有10、20等,后面打印img,发现最后通道数补充的都是0,可能图像分割切分的有问题。
使用mmcv相关的包mmaction出现的问题
cv2.error: OpenCV(4.5.5) D:\a\opencv-python\opencv-python\opencv\modules\core\src\arithm.cpp:650: error: (-209:
问题描述
错误位置
File "D:\miniconda3\lib\site-packages\mmcv\image\photometric.py", line 47, in imnormalize_
cv2.subtract(img, mean, img) # inplace
错误信息:
cv2.error: OpenCV(4.5.5) D:\a\opencv-python\opencv-python\opencv\modules\core\src\arithm.cpp:650: error: (-209:Sizes of input arguments do not match) The operation is neither 'array op array' (where arrays have the same size and the same number of channels), nor 'array op scalar', nor 'scalar op array' in function 'cv::arithm_op'
原因分析:
container = decord.VideoReader(file_obj, num_threads=self.num_threads)
在loading.py文件的(965行)的代码decord.VideoReader数据加载出的问题,在视频取每一帧将图片读取成4通道,也就是图片加载的shape是HxWx4或者是其他,在进到VideoReader里面,可以找到对应加载图片张量的代码
self._handle = _CAPI_VideoReaderGetVideoReader(
ba, ctx.device_type, ctx.device_id, width, height, num_threads, 2, fault_tol)
def get_batch(self, indices):
"""Get entire batch of images. `get_batch` is optimized to handle seeking internally.
Duplicate frame indices will be optmized by copying existing frames rather than decode
from video again.
Parameters
----------
indices : list of integers
A list of frame indices. If negative indices detected, the indices will be indexed from backward
Returns
-------
ndarray
An entire batch of image frames with shape NxHxWx3, where N is the length of `indices`.
"""
assert self._handle is not None
indices = _nd.array(self._validate_indices(indices))
arr = _CAPI_VideoReaderGetBatch(self._handle, indices)
return bridge_out(arr)
arr就是获取的图像矩阵,但_CAPI_VideoReaderGetBatch函数进不去,不知道是怎么将每一帧图片怎么变成三位矩阵的,但从数据上来看,3万多的数据,只有很少一部分吧(1000左右)出现问题,严格的说应该数据本身有问题,但在播放器里面一样可以播放,也同样可以取得每一帧,所以问题还没有从根本解决,只是在工程上去避免,不让程序在进来数据崩掉,这是在工业上的一个解决方案吧,如果有遇到同样问题的,可以讨论一下,也可以在下面留言。
解决方案:
找到对应报错模块:Video-Swin-Transformer\mmaction\datasets\pipelines\augmentations.py
在读取图片modality == “RGB”,修改为如下:
if modality == 'RGB':
n = len(results['imgs'])
h, w, c = results['imgs'][0].shape
if c <= 3:
imgs = np.empty((n, h, w, c), dtype=np.float32)
else:
imgs = np.empty((n, h, w, c), dtype=np.float32)
imgs = imgs[:, :, :, :3]
for i, img in enumerate(results['imgs']):
imgs[i] = img[:, :, :3]
for img in imgs:
# mmcv.imnormalize_(img, self.mean, self.std, self.to_bgr)
try:
mmcv.imnormalize_(img, self.mean, self.std, self.to_bgr)
except:
print(results["filename"])
i += 1
img = img.astype(np.float32)
mmcv.imnormalize_(img, self.mean, self.std, self.to_bgr)
results['imgs'] = imgs
results['img_norm_cfg'] = dict(
mean=self.mean, std=self.std, to_bgr=self.to_bgr)
return results
修改后数据特征会发生变化,即图像映射的张量会发生变化,特征会变少,大家可以根据自己的判断来处理。在进行分类任务时,您可以对训练集本身进行更改。同样让模型学习,可以比较数据的影响,也可以去掉这样的数据,或者给其他标签,可以根据自己的想法进行修改。
文章出处登录后可见!