데이터 어그멘테이션 albumentations모듈 (좌우반전) 에러 질문입니다

현재 데이터증강 작업을 수행하기위해 이미지크기 조절 수행및 이미지 좌우 반전수행을 진행중입니다 사용모듈은 import albumentations as A 사용중입니다

이때 이미지크기 조절은 transform = A.Compose([
A.Resize(height=800, width=800),
A.Normalize(mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225)),
ToTensorV2()
], bbox_params=A.BboxParams(format='coco', label_fields=['labels']), is_check_shapes=False) 으로 800 800 으로 바꾼후 정규화 과정을 수행하여 정상실행되고 결과사진도 문제없이 작동합니다

이제 이미지좌우반전을 수행하기위해서
transform_rotation = A.Compose([
A.HorizontalFlip(p=1),
A.Normalize(mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225)),
ToTensorV2()
], bbox_params=A.BboxParams(format='coco', label_fields=['labels']), is_check_shapes=False)

똑같이 A.HorizontalFlip을 수행하였는데 OpenCV(4.8.0) D:\a\opencv-python\opencv-python\opencv\modules\core\src\matrix_transform.cpp:780: error: (-215:Assertion failed) _src.dims() <= 2 in function 'cv::flip 이러한 에러가 발생합니다 이미지 차원이 안맞는것같은데

DataLoader에서는 if self.transforms is not None:
image = np.array(image)
transformed = self.transforms(image=image, bboxes=target['bbox'], mask=target['masks'],
labels=target['labels'], area=target['area'], iscrowd=target['iscrowd']) 명시적으로 전부 인자를 주었는데 에러가 발생합니다 원인이 무엇일까요 ...??

target형태입니다

  if self.transforms is not None:
            image = np.array(image)
            transformed = self.transforms(image=image, bboxes=target['bbox'], masks=target['masks'],
                                          labels=target['labels'], area=target['area'], iscrowd=target['iscrowd'])
            buffer = transformed['bboxes']
            del transformed['bboxes']
            transformed['bbox'] = buffer
            buffer = transformed['masks']
            del transformed['masks']
            transformed['masks'] = buffer
            image = transformed['image']
            del transformed['image']

            target = {key: transformed[key] for key in target}


        print("target shape : ",target['masks'][0].shape)
        print("target dtpye : ",type(target['masks']))
        target['boxes'] = torch.as_tensor(target['bbox'], dtype=torch.float32)
        target['masks'] = np.array([np.array(mask) for mask in target['masks']])
        target['masks'] = torch.as_tensor(target['masks'], dtype=torch.uint8)
        target['labels'] = torch.as_tensor(target['labels'], dtype=torch.int64)
        target['area'] = torch.as_tensor(target['area'], dtype=torch.float32)
        target['iscrowd'] = torch.as_tensor(target['iscrowd'], dtype=torch.int64)

transformed = self.transforms(image=image, bboxes=target['bbox'], masks=target['masks'],
                                          labels=target['labels'], 

masks = target['masks'] mask에서 masks 으로 수정 
  target['masks'] = np.array([np.array(mask) for mask in target['masks']]) 추가 


해결은되었는데 masks가 제대로 변화되었는지 확인안해서 불확실할수있습니다
  • 아래 답변은 OpenAI의 GPT-4 모델로 자동 생성한 것으로, 정확하지 않을 수 있습니다.
  • 잘못된 답변을 보셨다면 댓글로 첨삭 지도 부탁드립니다. :sweat_smile:

안녕하세요, KELLO83님. PyTorch와 albumentations를 사용하시는 것으로 보아 이미지 처리 작업에 많은 노력을 기울이고 계신 것 같습니다. 질문 내용을 정리해보면, albumentations 모듈을 사용하여 이미지 크기 조절과 정규화는 잘 수행되었지만, 이미지의 좌우 반전을 수행하려 할 때 OpenCV에서 차원 관련 에러가 발생하는 것으로 이해했습니다.

이 문제는 albumentations의 HorizontalFlip 함수가 이미지의 차원을 제대로 인식하지 못해서 발생하는 것으로 보입니다. HorizontalFlip 함수는 3차원 이미지(높이, 너비, 채널)에 대해 작동하도록 설계되었습니다. 따라서, 입력 이미지가 이 형태가 아니라면 에러가 발생할 수 있습니다.

이미지의 차원을 확인해보시는 것이 좋을 것 같습니다. 아래와 같이 코드를 작성하여 이미지의 차원을 확인해볼 수 있습니다.

print(image.shape)

만약 이미지가 grayscale(흑백)이라면 채널 차원이 없을 수 있습니다. 이 경우, 채널 차원을 추가해주어야 합니다. 아래와 같이 코드를 작성하여 채널 차원을 추가할 수 있습니다.

if len(image.shape) == 2:  # If the image is grayscale
    image = image[:, :, np.newaxis]  # Add channel dimension

또한, HorizontalFlip 함수를 사용하기 전에 이미지의 데이터 타입이 uint8인지 확인해보시는 것도 좋습니다. albumentations는 이미지의 데이터 타입이 uint8일 때 가장 잘 작동합니다. 아래와 같이 코드를 작성하여 이미지의 데이터 타입을 확인하고 필요하다면 변경할 수 있습니다.

print(image.dtype)
if image.dtype != np.uint8:
    image = image.astype(np.uint8)

위의 방법들로도 문제가 해결되지 않는다면, albumentations의 HorizontalFlip 함수 대신에 OpenCV의 flip 함수를 사용해보시는 것도 한 방법입니다. 아래와 같이 코드를 작성하여 OpenCV의 flip 함수를 사용할 수 있습니다.

image = cv2.flip(image, 1)  # 1 is for horizontal flipping, 0 for vertical

이러한 방법들을 통해 문제를 해결해보시기 바랍니다. 추가적인 질문이나 문제가 있으시다면 언제든지 물어보세요.

참고하실 수 있는 albumentations와 OpenCV에 대한 자세한 정보는 아래의 링크에서 확인하실 수 있습니다.

답변이 도움이 되었길 바라며, 제 답변이 틀릴 수도 있음을 이해해주시기 바랍니다. 감사합니다.


  • 답변이 어떠셨나요? 괜찮았다고 생각하신다면 아래 :heart:를 한 번 눌러주시길 부탁드려요!
  • 아래 답변은 Anthropic의 Claude-2 모델로 자동 생성한 것으로, 정확하지 않을 수 있습니다.
  • 잘못된 답변을 보셨다면 댓글로 첨삭 지도 부탁드립니다. :sweat_smile:

안녕하세요 KELLO83님,

좌우반전 에러에 대한 질문 감사합니다. 제가 이해한 바로는 albumentations의 HorizontalFlip에서 발생한 OpenCV 에러로, 이미지 차원 문제인 것 같다는 내용이 맞죠?

OpenCV의 flip 함수는 2차원 이미지 매트릭스에서만 동작하므로, 3차원 또는 그 이상의 차원을 가진 이미지에서 에러가 발생한 것으로 보입니다.

해결방안은 DataLoader에서 image를 불러올 때 차원을 확인하고, 필요하다면 squeeze() 등의 방법으로 2차원으로 변환한 후 HorizontalFlip을 적용하는 것이 좋을 것 같습니다.

if image.ndim > 2: 
   image = image.squeeze() # 차원 축소

transformed = transform_rotation(image=image, bboxes=target['bbox']...) 

또는 transform_rotation을 정의할 때 이미지 차원을 확인하고 변환하는 로직을 추가하는 것도 방법이 될 수 있겠습니다.

추가로, HorizontalFlip 보다는 torchvision.transforms의 RandomHorizontalFlip을 사용하는 것이 더 간편할 수 있습니다.

KELLO83님의 질문을 잘 이해하고 답변드리고자 노력했습니다. 만약 잘못 알고 있는 부분이 있다면 언제든지 의견 주세요. 함께 문제를 해결해 나가겠습니다.


  • 답변이 어떠셨나요? 괜찮았다고 생각하신다면 아래 :heart:를 한 번 눌러주시길 부탁드려요!
  • 아래 답변은 OpenAI의 GPT-3.5(ChatGPT) 모델로 자동 생성한 것으로, 정확하지 않을 수 있습니다.
  • 잘못된 답변을 보셨다면 댓글로 첨삭 지도 부탁드립니다. :sweat_smile:

안녕하세요 KELLO83님,

먼저, 데이터 어그멘테이션 작업을 수행하면서 발생한 문제에 대해 이해하고 정리해보겠습니다.

주어진 코드에서는 albumentations 모듈을 사용하여 이미지 크기 조절과 좌우 반전을 수행하려고 합니다. 이미지 크기 조절은 정상적으로 작동하며, 문제 없이 결과 이미지를 얻을 수 있습니다. 그러나 이미지 좌우 반전을 수행하려고 할 때 cv::flip 함수에서 에러가 발생합니다. 또한, DataLoader에서도 명시적으로 모든 인자를 전달했음에도 불구하고 에러가 발생합니다.

이제 이 문제를 해결하기 위한 해결책을 설명하겠습니다.

먼저, cv::flip 함수에서 발생하는 에러는 이미지의 차원이 맞지 않아서 발생하는 것으로 보입니다. cv::flip 함수는 2차원 이미지에 대해서만 작동하기 때문에, 이미지의 차원을 확인해야 합니다. 만약 이미지가 2차원이 아니라면, 이미지를 2차원으로 변환해야 합니다.

이미지를 2차원으로 변환하는 방법은 다음과 같습니다.

image = np.array(image)
if len(image.shape) == 3:
    image = image.transpose(1, 2, 0)

위의 코드를 A.HorizontalFlip 전에 추가하여 이미지를 2차원으로 변환한 후 좌우 반전을 수행하면 됩니다.

또한, DataLoader에서 발생하는 에러는 transforms 인자에 모든 필요한 인자를 전달했음에도 불구하고 발생하는 것으로 보입니다. 이 경우, transforms 인자에 전달하는 image 인자의 형식을 확인해야 합니다. image 인자는 numpy 배열이어야 하며, 만약 이미지가 PIL 이미지 형식이라면 numpy 배열로 변환해야 합니다.

image = np.array(image)

위의 코드를 DataLoader에서 image 인자를 전달하기 전에 추가하여 PIL 이미지를 numpy 배열로 변환하면 됩니다.

이제 위의 해결책을 적용한 예제 코드를 제시하겠습니다.

import albumentations as A
import numpy as np
from PIL import Image

# 이미지 크기 조절
transform_resize = A.Compose([
    A.Resize(height=800, width=800),
    A.Normalize(mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225)),
    A.ToTensorV2()
], bbox_params=A.BboxParams(format='coco', label_fields=['labels']), is_check_shapes=False)

# 이미지 좌우 반전
transform_flip = A.Compose([
    A.Lambda(image=lambda x: np.array(x)),
    A.Lambda(image=lambda x: x.transpose(1, 2, 0) if len(x.shape) == 3 else x),
    A.HorizontalFlip(p=1),
    A.Normalize(mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225)),
    A.ToTensorV2()
], bbox_params=A.BboxParams(format='coco', label_fields=['labels']), is_check_shapes=False)

# 이미지 로드
image = Image.open('image.jpg')

# 이미지 크기 조절 수행
transformed_resize = transform_resize(image=image)

# 이미지 좌우 반전 수행
transformed_flip = transform_flip(image=image)

위의 코드에서 transform_resize는 이미지 크기 조절을 위한 변환 함수를 정의하고, transform_flip은 이미지 좌우 반전을 위한 변환 함수를 정의합니다. 이미지를 로드한 후 transform_resize를 적용하면 이미지 크기가 조절된 이미지를 얻을 수 있고, transform_flip을 적용하면 이미지가 좌우로 반전된 이미지를 얻을 수 있습니다.

더 자세한 내용은 아래의 링크를 참고하시기 바랍니다.

이 답변이 도움이 되었는지 확인해 주시고, 추가로 궁금한 점이 있다면 언제든지 물어보세요!


  • 답변이 어떠셨나요? 괜찮았다고 생각하신다면 아래 :heart:를 한 번 눌러주시길 부탁드려요!