새로워지기/마흔의 생활코딩

LLM | ollama 5부. 이미지 인식 적용하기

청춘만화 2024. 2. 25. 22:56

LLM | ollama 5부. 이미지 인식 적용하기

- ollama 1부. 로컬 터미널에서 실행하기 : Linux(wsl 2), MacOS 
- ollama 2부. 로컬 브라우저에서 실행하기 open-webui
- ollama 3부. 온라인(내 도메인으로) 브라우저에서 실행하기 
ollama 4부. 검색증강 RAG 적용하기
👉   ollama 5부. 이미지 인식 적용하기 
- (준비 중) ollama 6부. MOE mixture of exports 방식 적용하기

 

 

 

 

이미지 인식 모델 :13b

ollama에서 제공하는 모델 중 이미지 인식( 비전 vision) LLM 모델로는 Llava가 있다. Llava를 통해 제공할 수 있는 기본 기능에 대해 조금 더 구체적인 표현으로는 Image Annotator App라고 할 수 있다. 그리고 이 모델은 llava:7b, llava:13b, llava:34b 유형이 있는데 (일반적으로 사용하는 언어 모델과 달리 이미지 모델인 llava의 경우,,)7b는 성능이 기대만큼 나오지 않아서 많은 경우 13b를 사용한다.  

1. Work Flow
  1) get the file list from a folder
  2) load the file and convert to bytes
  3) Send the file to Llava 1.6 via Ollama
  4) save the results back to the DataFrame
  5) Save the dataframe to csv

 

2. 코드 

from ollama import generate
import glob
import pandas as pd
from PIL import Image
import os
from io import BytesIO

def load_or_create_dataframe(filename):
    if os.path.isfile(filename):
        df = pd.read_csv(filename)
    else:
        df = pd.DataFrame(columns=['image_file', 'description'])
    return df

# CSV 파일에서 데이터프레임을 로드하거나 파일이 없는 경우 새 파일을 만듭니다.
df = load_or_create_dataframe('image_descriptions.csv')

def get_png_files(folder_path):
    return glob.glob(f"{folder_path}/*.png")

# 처리하려는 폴더의 이미지 파일 목록을 가져와서 오름차순으로 정렬합니다 
image_files = get_png_files("./images") 
image_files.sort()
print(df.head())

# 이미지 처리(by.PIL) + LLM로 설명 생성 + 데이터 프레임에 행(레코드 또는 row) 추가 프로세스  
def process_image(image_file):
    print(f"\\nProcessing {image_file}\\n")
    with Image.open(image_file) as img:
        with BytesIO() as buffer:
            img.save(buffer, format='PNG')
            image_bytes = buffer.getvalue()

    full_response = ''
    # 이미지에 대한 설명 생성하기
    for response in generate(model='llava:13b', 
                             prompt='describe this image and make sure to include anything notable about it (include text you see in the image):', 
                             images=[image_bytes], 
                             stream=True):
        # 콘솔에 응답을 인쇄하고 전체 응답에 추가합니다.
        print(response['response'], end='', flush=True)
        full_response += response['response']

    # 데이터프레임에 새 행을 추가합니다.
    df.loc[len(df)] = [image_file, full_response]

## (이미지 폴더 안에 있는) 이미지 파일 목록 중에 
for image_file in image_files:
    # '새로운 파일 이름'이 발견되면 
    if image_file not in df['image_file'].values:
        # 이미지 설명을 생성하는 'process_image('새로운 파일이름')'함수를 실행  
        process_image(image_file)

# 데이터프레임을 CSV 파일로 저장합니다.
df.to_csv('image_descriptions.csv', index=False)

*참고로, 이미지를 읽는 대표적인 방법에는 OpenCV를 사용해서 읽는 방법과 PIL를 이용해서 읽는 방법이 있다. 이번 예제는 PIL를 사용한예제이다. (참고로2, 최근?에는 Binary(byte 단위) 형태로 읽어서 처리하는 방법도 있다고 하니 참고하면 좋을 듯하다) 

 

 

3. 결과

(1) : 이미지 인식을 처음 실행한 케이스 
    - 프로세스 
      1) 빈 csv 파일(dataframe( 레코드 또는 row)을 담을 빈 테이블( 또는 컬럼))을 생성하고
      2) llava가 생성한 '이미지 설명'을 '이미지 이름'과 함께  dataframe로 생성하고 그 내용을.
      3) csv에 담는다. 
    - 이미지 설명 
      1) (실행할 때마다 다르긴 한데.. 대체적으로)
           이미지 내용(표현)적인 측면과 데이터(유형)적인 측면 두 가지로 나누어 설명을 해주고 있다.

(2) : 폴더에 동일 이미지가 있는데 반복해서 실행하는 경우 
    - 프로세스 
      1) 이전에 csv에 저장했던 내역을 출력해준다. 

+ : 폴더에 새로운 이미지를 추가하면 해당 이미지에 대한 설명 글을 생성한 후 추가로 저장한다. 

 

 

 

(참고로 이미지 설명 결과 중 일부는 아래와 같다.. ㅎㄷㄷ  DeepL을 통해 한글로 번역..)


이 이미지에는 인기 인터넷 밈 "개구리 페페"의 스타일에서 영감을 받은 것으로 보이는 캐릭터의 일러스트가 있습니다. 이 캐릭터는 큰 눈과 큰 코 등 독특한 얼굴 특징이 특징입니다. 이 캐릭터는 한 손을 턱 가까이 올린 채 사려 깊은 포즈를 취하고 있어 사색이나 깊은 생각을 하고 있음을 암시합니다. 이미지 자체에는 텍스트가 없습니다.

이 이미지는 영화 '헝거게임' 시리즈에 등장하는 캐릭터를 보여줍니다. 이 캐릭터는 영화에서 캣니스 에버딘을 연기한 제니퍼 로렌스가 연기했습니다. 그녀는 진지한 표정으로 가죽과 같은 디테일이 있는 어두운 튜닉과 등에 화살통이 달린 의상을 입고 있습니다. 그녀의 머리는 책과 영화 속 캣니스의 캐릭터와 비슷한 방식으로 스타일링되어 있습니다. 이 이미지는 영화 시리즈의 홍보 자료이거나 '헝거게임' 시리즈와 관련된 일러스트레이션일 가능성이 높습니다.

이 이미지는 애니메이션 및 만화 시리즈 "드래곤볼"의 캐릭터 손오공을 컬러풀하게 표현한 일러스트입니다. 뾰족한 황금색 머리카락이 특징인 슈퍼 사이어인의 모습으로 묘사되어 있습니다. 손오공은 특유의 주황색 무술복을 입고 양쪽 손목에 검은색 팔찌를 차고 허리에 파란색 띠를 두르고 있습니다. 손오공은 양손을 양쪽으로 뻗어 정면을 바라보며 액션 포즈를 취하고 있습니다. 이미지의 배경은 평범한 흰색으로 캐릭터에 초점을 맞춥니다. 이미지에는 텍스트가 없습니다.

이 이미지에는 도시 환경으로 보이는 책상에 한 남성이 앉아 있는 모습이 담겨 있습니다. 그는 밝은 빨간색 셔츠와 검은색 바지를 입고 손을 책상 앞에 올려놓고 있습니다. 그의 표정은 집중되어 있으며, 아래를 내려다보거나 프레임 밖의 무언가를 바라보고 있는 것처럼 보입니다.
조명과 구도로 보아 영화나 텔레비전 프로덕션에서 가져온 것으로 보이는 이 설정은 이러한 미디어의 전문적인 연출을 나타내는 경우가 많습니다. 배경에 흐릿한 조명이 있어 인공 조명이 있는 실내임을 나타냅니다. 책상 위에는 빨간색 아이콘이 표시된 컴퓨터 모니터가 있지만 화면의 내용은 보이지 않습니다. 
책상 위에는 사무실 환경에서 흔히 볼 수 있는 펜꽂이, 종이, 전자 기기 또는 케이블과 같은 다른 물체도 있습니다. 이미지의 전체적인 분위기는 남자의 표정과 주변 조명으로 인해 침울하거나 사색에 잠긴 것처럼 보입니다.