cv2.error: OpenCV(4.5.5) D:\a\opencv-python\opencv-python\opencv\modules\core\src\arithm.cpp:650: er

项目场景: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

修改完以后数据特征会发生变化,也就是图片映射的张量发生了变化,特征会少一部分,所以根据自己的判断可以进行处理,在做分类任务,你可以在训练集本身就进行更改,同样让模型进行学习,可以比对一下该数据的影响,也可以将这样数据移除,或者另给予其他标签,可根据自己的想法进行更改。

你可能感兴趣的:(mmcv,mmaction,pytorch环境,python,opencv,图像处理)