프로젝트를 진행하면서 유사한 이미지를 추천해 주는 기능을 위해서 Vision을 이용해 사진에 라벨링 하는 기능을 구현했는데 복습하며 정리해 보도록 하겠다
Google Cloud Console을 먼저 세팅하자
https://cloud.google.com/vision/docs/setup?hl=ko
해당 문서를 따라서 설정을 하면 json으로 된 키파일을 다운받을 수 있다 안전하게 보관해 두자
필요한 패키지를 먼저 다운로드하고 시작하자
npm install @google-cloud/vision --save
google vision api를 사용하기 위해서 class를 만들자
import vision, { ImageAnnotatorClient } from '@google-cloud/vision';
import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import * as _ from 'lodash';
@Injectable()
export class GoogleVisionService {
client: ImageAnnotatorClient;
constructor(private configSerivce: ConfigService) {
const googlePrivateKey = this.configSerivce.get('GOOGLE_VISION_API_SECRET_KEY');
const clientEmail = this.configSerivce.get('GOOGLE_VISION_API_CLIENT_EMAIL');
this.client = new vision.ImageAnnotatorClient({
credentials: {
private_key: googlePrivateKey,
client_email: clientEmail,
},
});
}
async imageLabeling(image: string) {
return this.client
.labelDetection(image)
.then((results) => {
const labels = results[0].labelAnnotations;
if (_.isNil(labels)) return [];
const result = labels.map((label) => {
if (_.isString(label.description)) {
return label.description;
}
});
return [...new Set(result)];
})
.catch((err) => {
console.log('error: ', err);
return [];
});
}
}
아까 받은 json파일에서 API 시크릿키와 API 이메일을 가지고 vision 클라이언트를 생성하고 사용한다
imageLabeling에서 매개변수로 받은 이미지를 labelDetection메세드를 사용해서 해당 이미지에 대한 라벨링을 진행한다
중복되는 라벨이 존재하기 때문에 Set을 이용해서 중복값을 제거한 후 반환한다
만든 GoogleVisionService클래스를 사용하러 가보자
photospot.module에 의존성 주입을 시킨다
providers: [PhotospotService, S3Service, GoogleVisionService],
그리고 photospot.service로 가보자
async createImageKeyword(image: string, photoId: number): Promise<void> {
const photoKeywords = await this.googleVisionService.imageLabeling(image);
const keyword = [];
for (const photoKeyword of photoKeywords) {
if (_.isUndefined(photoKeyword)) {
continue;
}
const preKeyword = await this.photoKeywordRepository.findOne({ where: { keyword: photoKeyword } });
if (_.isNil(preKeyword)) {
const insertKeyword = await this.photoKeywordRepository.save({ keyword: photoKeyword });
keyword.push(insertKeyword);
} else {
keyword.push(preKeyword);
}
}
const photo = await this.photoRepository.findOne({ where: { id: photoId } });
if (_.isNil(photo)) {
return;
}
photo.photoKeywords = keyword;
await this.photoRepository.save(photo);
}
포토스팟을 등록하는 부분에서 포토스팟에 포토를 등록하고 후 createImageKeyword를 호출한다
그렇다면 전달받은 이미지와 포토아이디를 가지고 라벨링 후 DB에 저장한다
이미 존재하는 키워드에 경우에는 중복되어 저장되는 걸 막기 위해서 preKeyword로 따로 지정하고
새로운 키워드의 경우 새로 만들어 저장 후 insertKeyword로 지정한다 그리고 각각 keyword 배열에 집어넣는다
포토아이디를 가지고 라벨링이 돼야 하는 해당 포토를 가져와 photoKeywords 컬럼을 keyword로 재할당 후 save를 시키는 방식으로 사진에 라벨링을 한다
'과거공부모음' 카테고리의 다른 글
Nest.js log를 파일로 만들어서 관리 (logging) (0) | 2023.04.02 |
---|---|
TypeORM 추진 추천 쿼리 (0) | 2023.04.02 |
Nest.js에서 이미지를 S3에 업로드 (0) | 2023.04.01 |
Nest.js에서 Multer를 이용해 여러 장의 이미지 파일 관리 (0) | 2023.04.01 |
20230324 TIL - 사진 리사이징 (0) | 2023.03.25 |