numpy.frombuffer & cv2.imencode & cv2.imdecode

About_work·2024년 2월 21일
0

python 기초

목록 보기
36/65

1. numpy.frombuffer

  • buffer란? buffer protocol이란? : https://velog.io/@jk01019/buffer란-buffer-protocol이란
  • numpy.frombuffer 함수는 바이트 데이터를 numpy 배열로 변환하는 데 사용
  • 이 함수는 버퍼와 같은 바이트 객체를 입력으로 받아, 지정된 데이터 타입(dtype)에 맞게 배열을 생성
  • 데이터의 복사본을 만들지 않고, 원본 메모리 버퍼에 대한 뷰(view)를 생성
  • 이 방법은 바이너리 데이터를 빠르게 numpy 배열로 읽어들일 때 유용하며, 파일로부터의 데이터 읽기, 네트워크 통신을 통한 큰 데이터 수신 등 다양한 상황에서 활용

1.1. 사용법

numpy.frombuffer(buffer, dtype=float, count=-1, offset=0)
  • buffer:
    • 바이트 데이터를 포함하는 객체
    • 이 객체는 buffer 프로토콜을 지원해야 하며,
    • bytes 또는 bytearray와 같은 타입이 될 수 있습니다.
  • dtype:
    • 배열의 원소 타입을 지정
    • 기본값은 float이지만, int, float32, uint8 등 다양한 numpy 데이터 타입을 지정할 수 있습니다.
  • count:
    • 읽어들일 원소의 수를 지정
    • 기본값은 -1로, 이는 가능한 모든 원소를 읽어들이라는 의미입니다.
  • offset:
    • 버퍼의 시작 위치로부터의 오프셋(바이트 단위)
    • 데이터를 읽기 시작할 위치를 지정할 수 있습니다.
    • 기본값은 0입니다.

1.2. 예제

import numpy as np

# 바이트 데이터 예제
data = b'\x01\x02\x03\x04'
# 바이트 데이터를 uint8 타입의 numpy 배열로 변환
arr = np.frombuffer(data, dtype=np.uint8)
print(arr)
  • 이 예제에서는 바이트 객체 datanumpy 배열 arr로 변환합니다. dtype으로 np.uint8을 지정하여, 각 바이트를 8비트 부호 없는 정수로 해석합니다.

1.3. 주의사항

  • frombuffer입력된 버퍼의 복사본을 만들지 않고, 기존 버퍼에 대한 뷰(view)를 생성
  • 따라서, 생성된 numpy 배열을 수정하면 원본 버퍼의 내용도 변경될 수 있습니다.
  • 버퍼의 크기가 dtype으로 지정된 타입의 크기로 정확히 나누어떨어지지 않으면, ValueError가 발생할 수 있습니다.
  • 데이터 구조를 정확히 알고 있어야 하며, 올바른 dtype을 지정해야 합니다.

2. cv2.imencode

  • cv2.imencode: 이미지를 특정 포맷의 메모리 버퍼로 인코딩
    • 디스크에 파일을 저장하지 않고, 이미지를 바이너리 형태로 직접 변환할 때 유용
    • 네트워크를 통해 이미지를 전송하거나 데이터베이스에 저장할 때 사용

파라미터

  1. ext (문자열):
  • 인코딩할 이미지 포맷을 지정하는 파일 확장자
  • 예를 들어, JPEG 포맷으로 인코딩하려면 '.jpg' 또는 '.jpeg'를, PNG 포맷으로 인코딩하려면 '.png'를 사용
  1. img (NumPy 배열)
  • 인코딩할 이미지 데이터
  • OpenCV에서 이미지는 NumPy 배열로 표현
  1. params (정수의 리스트, 선택적):
  • 인코딩 과정에서 사용할 파라미터를 지정하는 리스트
  • 이는 선택적 파라미터이며, 포맷에 따라 다양한 옵션을 설정할 수 있습니다.
  • 예를 들어, JPEG 이미지를 인코딩할 때 품질을 지정하려면
    • [int(cv2.IMWRITE_JPEG_QUALITY), 95]와 같이 사용할 수 있습니다.
    • 여기서 95는 품질 수준을 의미합니다.

반환 값

cv2.imencode 함수는 두 가지 값을 반환합니다:

  1. retval (부울): 인코딩이 성공적으로 완료되었는지를 나타내는 부울 값입니다. 성공하면 True, 실패하면 False를 반환합니다.
  2. buf (바이트 배열): 인코딩된 이미지 데이터를 포함하는 메모리 버퍼입니다. 이 데이터는 파일 시스템에 저장하거나 네트워크를 통해 전송할 수 있습니다.

예제 코드

다음은 cv2.imencode를 사용하여 이미지를 JPEG 포맷으로 인코딩하고, 인코딩된 바이트 배열을 파일로 저장하는 예제입니다:

import cv2
import numpy as np

# 이미지 로드
image = cv2.imread('image.jpg')

# JPEG 포맷으로 이미지 인코딩
retval, buffer = cv2.imencode('.jpg', image, [int(cv2.IMWRITE_JPEG_QUALITY), 95])

if retval:
    # 인코딩된 바이트 배열을 파일로 저장
    with open('encoded_image.jpg', 'wb') as f:
        f.write(buffer)
  • 이 코드는 주어진 이미지를 JPEG 포맷으로 인코딩하고, 설정한 품질로 메모리 버퍼에 저장한 후, 이 버퍼를 파일 시스템에 encoded_image.jpg로 저장합니다.

2. np.array(buf).tobytes()

  • np.array(buf).tobytes() 부분에서는 인코딩된 이미지 데이터(buf)를 NumPy 배열로 변환한 후, .tobytes() 메서드를 사용하여 이 배열을 바이트 문자열로 변환
  • np.array(buf): buf에 저장된 데이터를 NumPy 배열 형태로 변환합니다. 이는 메모리 내의 데이터를 효율적으로 관리하고 처리하는 데 도움을 줍니다.
  • .tobytes(): NumPy 배열의 내용을 순수한 바이트 데이터로 변환합니다. 이 바이트 데이터는 ROS 메시지의 data 필드에 저장되어 퍼블리싱 될 수 있습니다.

3. cv2.imdecode

  • cv2.imdecode 함수는 메모리 버퍼에서 이미지 데이터를 읽어들여 numpy 배열로 디코딩하는 데 사용
  • 이 함수는이미지 파일을 직접 파일 시스템에서 읽지 않고, 메모리 내의 이미지 데이터를 처리할 때 유용
  • cv2.imdecode 함수는 메모리에 저장된 바이너리 이미지 데이터를 직접 디코딩할 수 있으므로, np.frombuffer를 먼저 호출할 필요가 없습니다.
  • cv2.imdecode는 바이너리 형태의 이미지 데이터를 numpy 배열로 변환하는 과정에서 이미지 포맷을 자동으로 인식하고 적절히 디코딩합니다.
  • 따라서, 바이너리 이미지 데이터를 처리할 때는 cv2.imdecode만 사용하면 충분합니다.

사용법

기본적인 사용법은 다음과 같습니다:

cv2.imdecode(buf, flags)
  • buf: 이미지 데이터를 포함하는 바이트 시퀀스입니다. 일반적으로 bytes 또는 bytearray 객체를 사용합니다.
  • flags: 이미지를 읽는 방식을 지정합니다. 예를 들어, 이미지를 그레이스케일로 읽거나, 컬러로 읽는 등의 옵션을 지정할 수 있습니다. cv2.IMREAD_COLOR, cv2.IMREAD_GRAYSCALE, cv2.IMREAD_UNCHANGED 등이 자주 사용됩니다.

예시

메모리 내의 이미지 데이터를 컬러로 디코딩하는 예시입니다:

import cv2
import numpy as np

# 이미지 데이터를 바이트 배열로 가정
image_data = bytearray([...])  # 이미지 파일로부터 읽어온 바이트 데이터

# 바이트 배열을 numpy 배열로 변환
nparr = np.frombuffer(image_data, np.uint8)

# cv2.imdecode를 사용하여 numpy 배열을 이미지로 디코딩
img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)

# 이미지 표시 (예: imshow를 사용)
cv2.imshow('Image', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

이 예시에서는 메모리에 저장된 이미지 데이터 (image_data)를 numpy 배열로 변환한 다음, cv2.imdecode 함수를 사용하여 이 데이터를 컬러 이미지로 디코딩합니다. 디코딩된 이미지는 img에 저장되며, cv2.imshow를 통해 화면에 표시할 수 있습니다.

주의사항

  • cv2.imdecode 함수는 바이너리 이미지 데이터를 디코딩하기 위한 것으로, 이미지 파일의 경로를 직접 전달하면 안 됩니다. 이미지 파일의 내용을 먼저 바이트 시퀀스로 읽어들여야 합니다.
  • 이미지 데이터가 손상되었거나 지원하지 않는 형식일 경우, cv2.imdecodeNone을 반환할 수 있습니다. 따라서 반환값을 확인하는 것이 좋습니다.
profile
새로운 것이 들어오면 이미 있는 것과 충돌을 시도하라.

0개의 댓글