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

修改后数据特征会发生变化,即图像映射的张量会发生变化,特征会变少,大家可以根据自己的判断来处理。在进行分类任务时,您可以对训练集本身进行更改。同样让模型学习,可以比较数据的影响,也可以去掉这样的数据,或者给其他标签,可以根据自己的想法进行修改。

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
青葱年少的头像青葱年少普通用户
上一篇 2022年4月2日
下一篇 2022年4月2日

相关推荐