sqld 자격검정 실전문제 pdf 및 기출문제 덤프
채팅문의
전체 글
- [sqld] 기출문제 및 노랭이책 관련 2023.10.11
- MMdetection 설치 A-Z 2023.08.03
- [ObjectDetection] Keypoint 탐지 2023.08.01
- [전처리] 사진 여러장처럼 보이게만들기(Augmentation) 2023.06.16
- [전처리] 이미지 비율에 맞게 정사각형 만들기 2023.06.15
- [전처리] 가져온 사진 정보 받기 (feat, xml) 2023.06.15 1
- [전처리] 가져온 사진 정보 받기 (feat, json) 2023.06.14
- [전처리] 폴더에 있는 사진 가져오기 2023.06.14
- [CV] 영상 기본 세팅 6 (특징점기반 추적 feat, ORB + 불필요 특징점 제거2) 2023.06.12
- [CV] 영상 기본 세팅 5 (특징점기반 추적 feat, sift + 불필요 특징점 제거1) 2023.06.12
- [CV] 영상 기본 세팅 4 (특징점기반 추적 feat, kalman) 2023.06.12 1
- [CV] 영상 기본 세팅 3 (filter이해하기 feat, kalman) 2023.06.12 1
- [CV] 영상 기본 세팅 2 (객체추적) 2023.06.12
- [CV] 이미지 기본세팅 8 (확장 - dilation, 침식 - erosion) 2023.06.08
- [CV] 이미지 기본세팅 7 (필터효과) 2023.06.08
- [CV] 이미지 기본세팅 6 (머신러닝 특성 만들기-flatten()) 2023.06.08
- [CV] 이미지 기본세팅 4 (이미지 회전, 상하좌우반전) 2023.06.08 1
- [CV] 이미지 기본세팅 3 (블러, 선명도, 대비) 2023.06.08 2
- [CV] 이미지 기본세팅 2 (리사이징, 크롭) 2023.06.08
- [CV] 이미지 기본세팅 1 (불러오기, 저장하기) 2023.06.07
[sqld] 기출문제 및 노랭이책 관련
MMdetection 설치 A-Z
MMdetection을 사용하기 위한 초기 환경설정
1. 가상환경 구축
conda create -n mmdetection python=3.11 # ( 3.7 이상 버전이면 ok)
2. Pytorch 설치
conda install pytorch torchvision torchaudio pytorch-cuda=11.7 -c pytorch -c nvidia
3. MMCV-Full 설치
자신이 설치한 cuda 버전으로 설치해야합니다. 우리는 위에 11.7 설치했으므로 11.7 선택
pip install mmcv==2.0.0 -f https://download.openmmlab.com/mmcv/dist/cu117/torch2.0/index.html
가이드 주소 : https://mmcv.readthedocs.io/en/latest/get_started/installation.html#install-mmcv
4. Github 에서 mmdetection zip 다운로드 후 파이참 세팅 및 위에서 만든 가상환경으로 인터프린 트 설정
https://github.com/open-mmlab/mmdetection/archive/refs/heads/main.zip
or
git clone https://github.com/open-mmlab/mmdetection.git
5. install MMDetection (수동 설치) / cd명령어로 저장한 파일로 경로이동
pip install -r requirements/build.txt
pip install -v -e .
pip mmdet # 설치가 잘 됐는지 확인사살
'ComputerVision > [ObjectDetection]' 카테고리의 다른 글
[ObjectDetection] Keypoint 탐지 (0) | 2023.08.01 |
---|
[ObjectDetection] Keypoint 탐지
keypoint가 라벨링된 json 파일(train)을 이용하여 이미지에 적용하여 학습하여
나머지 이미지(test)로 keypoint 찾기
# keypointrcnn_resnet50_fpn 모델 이용한 Keypoint 실습
PyTorch 제공하는 Object detection reference training scripts 다운로드
- 다운로드 사이트 https://github.com/pytorch/vision/tree/main/references/detection
Customdataset.py
import torch
import json
import cv2
import numpy as np
import os
from torch.utils.data import Dataset
from torchvision.transforms import functional as F
class KeypointDataset(Dataset):
def __init__(self, root, transform=None, demo=False):
self.demo = demo
# Visualize를 통해 시각화로 확인하고자 할때 비교를 위한 변수
self.root = root
# 현재 데이터셋은 root 인자에 dataset 하위 폴더의 train, test 폴더를 택일하도록 되어 있음
self.imgs_files = sorted(os.listdir(os.path.join(self.root, "images")))
# 이미지 파일 리스트. train 또는 test 폴더 하위에 있는 images 폴더를 지정하고, 해당 폴더의 내용물을 받아옴
# 이미지를 이름 정렬순으로 불러오도록 sorted를 붙임
self.annotations_files = sorted(os.listdir(os.path.join(self.root, "annotations")))
# 라벨링 JSON 파일 리스트. 상기 images 폴더를 받아온 것과 동일
self.transform = transform
def __getitem__(self, idx):
img_path = os.path.join(self.root, "images", self.imgs_files[idx])
# 이번에 호출되는 idx번째 이미지 파일의 절대경로
annotations_path = os.path.join(self.root, "annotations", self.annotations_files[idx])
# 이번에 호출되는 idx번째 이미지 파일의 라벨 JSON 파일 경로
img_original = cv2.imread(img_path)
img_original = cv2.cvtColor(img_original, cv2.COLOR_BGR2RGB)
# 이미지를 읽은 후, BGR 순서를 RGB 형태로 바꿈
with open(annotations_path, "r", encoding="utf-8") as f:
data = json.load(f)
# 라벨 JSON 파일을 JSON 모듈로 받아옴
bboxes_original = data["bboxes"]
# JSON 하위 "bboxes" 키로 bbox 정보들이 담겨있음
keypoints_original = data["keypoints"]
# "keypoints" 키로 키포인트 정보가 담겨있음
bboxes_labels_original = ['Glue tube' for _ in bboxes_original]
# 현재 데이터셋은 모든 객체가 접착제 튜브이므로,
# 모든 bbox에 대해 일관적으로 'Glue tube'라는 라벨을 붙여줌
if self.transform: # if self.transform is not None:
# "keypoints": [
# [[1019, 487, 1], [1432, 404, 1]], [[861, 534, 1], [392, 666, 1]]
# ]
keypoints_original_flattened = [el[0:2] for kp in keypoints_original for el in kp]
# kp : [[1019, 487, 1]]
# el : [1019, 487, 1]
# el[0:2] : [1019, 487] (평면 이미지에서 3번째 축 요소는 필요없기 때문에 제거)
# keypoints_original_flattened = [[1019, 487], [1432, 404], [861, 534], [392, 666]]
# albumentation transform은 평면 이미지에 적용되므로 2차원 좌표만이 필요함
# albumentation 적용
transformed = self.transform(image=img_original, bboxes=bboxes_original,
bboxes_labels=bboxes_labels_original,
keypoints=keypoints_original_flattened)
img = transformed["image"] # albumentation transform이 적용된 image
bboxes = transformed["bboxes"]
keypoints_transformed_unflattened = np.reshape(np.array(transformed["keypoints"]), (-1, 2, 2)).tolist()
# transformed["keypoints"] : [1019, 487, 1432, 404, 861, 534, 392, 666]
# keypoints_transformed_unflattened : [[[1019, 487], [1432, 404]], [[861, 534], [392, 666]]]
keypoints = []
for o_idx, obj in enumerate(keypoints_transformed_unflattened):
obj_keypoints = []
# o_idx : 현재 순회중인 요소의 순번 (index)
# obj : 현재 순회중인 요소, ex) [[1019, 487], [1432, 404]]
for k_idx, kp in enumerate(obj):
# k_idx : 현재 순회중인 하위 요소의 순번 (index)
# kp : 현재 순회중인 요소, ex) [1019, 487]
obj_keypoints.append(kp + [keypoints_original[o_idx][k_idx][2]])
# torch.Tensor에서 벡터곱을 하는 과정에서 필요할 3번째 축 요소를 덧붙임 ex) [1019, 487, 1]
keypoints.append(obj_keypoints)
# Tensor 형태로 사용할 keypoints 리스트에 3번째 축 요소를 덧붙인 키포인트 좌표를 담음
else:
img, bboxes, keypoints = img_original, bboxes_original, keypoints_original
# transform이 없는 경우에는 변수 이름만 바꿔줌
# transform을 통과한 값들을 모두 tensor로 변경
bboxes = torch.as_tensor(bboxes, dtype=torch.float32)
# as_tensor 메서드가 list를 tensor로 변환할 때 속도 이점이 있음
target = {}
# keypoint 모델에 사용하기 위한 label이 dictionary 형태로 필요하므로, dict 형태로 꾸림
target["boxes"] = bboxes
target["labels"] = torch.as_tensor([1 for _ in bboxes], dtype=torch.int64)
# 모든 객체는 동일하게 접착제 튜브이므로, 동일한 라벨 번호 삽입
target["image_id"] = torch.tensor([idx])
# image_id는 고유번호를 지칭하는 경우도 있는데, 그러한 경우에는 JSON 파일에 기입이 되어있어야 함
# 이번 데이터셋은 JSON상에 기입되어있지 않으므로, 현재 파일의 순번을 넣어줌
target["area"] = (bboxes[:, 3] - bboxes[:, 1]) * (bboxes[:, 2] - bboxes[:, 0])
# 해당하는 bbox의 넓이.
# bboxes[:, 3] - bboxes[:, 1] : bboxes 내부 요소들의 (y2 - y1), 즉 세로 길이
# bboxes[:, 2] - bboxes[:, 0] : bboxes 내부 요소들의 (x2 - x1), 즉 가로 길이
target["iscrowd"] = torch.zeros(len(bboxes), dtype=torch.int64)
# 이미지상에 키포인트 또는 bbox가 가려져있는지를 묻는 요소
target["keypoints"] = torch.as_tensor(keypoints, dtype=torch.float32)
img = F.to_tensor(img)
# image의 텐서 변환
bboxes_original = torch.as_tensor(bboxes_original, dtype=torch.float32)
target_original = {}
target_original["boxes"] = bboxes_original
target_original["labels"] = torch.as_tensor([1 for _ in bboxes_original],
dtype=torch.int64) # all objects are glue tubes
target_original["image_id"] = torch.tensor([idx])
target_original["area"] = (bboxes_original[:, 3] - bboxes_original[:, 1]) * (
bboxes_original[:, 2] - bboxes_original[:, 0])
target_original["iscrowd"] = torch.zeros(len(bboxes_original), dtype=torch.int64)
target_original["keypoints"] = torch.as_tensor(keypoints_original, dtype=torch.float32)
img_original = F.to_tensor(img_original)
# demo=True일 경우, 원본 이미지와 변환된 이미지를 비교하기 위해 원본 이미지를 반환하기 위한 블록
if self.demo:
return img, target, img_original, target_original
else:
return img, target
def __len__(self):
return len(self.imgs_files)
if __name__ == "__main__":
root_path = "./keypoint_dataset"
train_dataset = KeypointDataset(f"{root_path}/train")
for item in train_dataset:
print(item)
visualize.py
import cv2
import albumentations as A
from Customdataset import KeypointDataset
from torch.utils.data import DataLoader
import matplotlib.pyplot as plt
import numpy as np
from utils import collate_fn
train_transform = A.Compose([
A.Sequential([
A.RandomRotate90(p=1), # 랜덤 90도 회전
A.RandomBrightnessContrast(brightness_limit=0.3, contrast_limit=0.3, brightness_by_max=True,
always_apply=False, p=1) # 랜덤 밝기 및 대비 조정
], p=1)
], keypoint_params=A.KeypointParams(format='xy'),
bbox_params=A.BboxParams(format="pascal_voc", label_fields=['bboxes_labels']) # 키포인트의 형태를 x-y 순으로 지정
)
root_path = "./keypoint_dataset/"
dataset = KeypointDataset(f"{root_path}/train/", transform=train_transform, demo=True)
# demo=True 인자를 먹으면 Dataset이 변환된 이미지에 더해 transform 이전 이미지까지 반환하도록 지정됨
data_loader = DataLoader(dataset, batch_size=1, shuffle=True, collate_fn=collate_fn)
iterator = iter(data_loader)
# for문으로 돌릴 수 있는 복합 자료형들은 iterable (반복 가능) 속성을 갖고 있음
# iter()로 그러한 자료형을 감싸면 iterator (반복자) 가 되고,
# next(iterator)를 호출하면서 for문을 돌리듯이 내부 값들을 순회할 수 있게 됨
batch = next(iterator)
# iterator에 대해 next로 감싸서 호출을 하게 되면,
# for item in iterator의 예시에서 item에 해당하는 단일 항목을 반환함
# 아래 4줄에 해당하는 코드와 같은 의미
# batch_ = None
# for item in data_loader:
# batch_ = item
# break
keypoints_classes_ids2names = {0: "Head", 1: "Tail"}
# bbox 클래스는 모두 접착제 튜브 (Glue tube) 로 동일하지만, keypoint 클래스는 위의 dict를 따름
def visualize(image, bboxes, keypoints, image_original=None, bboxes_original=None, keypoints_original=None):
# pyplot을 통해서 bbox와 키포인트가 포함된
# 원본 이미지와 변환된 이미지를 차트에 띄워서 대조할 수 있는 편의함수
fontsize = 18
# cv2.putText에 사용될 글씨 크기 변수
for bbox in bboxes:
# bbox = xyxy
start_point = (bbox[0], bbox[1])
# 사각형의 좌측 상단
end_point = (bbox[2], bbox[3])
# 사각형의 우측 하단
image = cv2.rectangle(image.copy(), start_point, end_point, (0, 255, 0), 2)
# 이미지에 bbox 좌표에 해당하는 사각형을 그림
for kpts in keypoints:
# keypoints : JSON 파일에 있는 keypoints 키의 값 (즉, keypoints 최상위 리스트)
# kpts : keypoints 내부의 각 리스트 (즉, 각 bbox의 키포인트 리스트)
for idx, kp in enumerate(kpts):
# kp : kpts 내부의 각 리스트 (즉, 키포인트 리스트 내부의 xy좌표쌍, 키포인트 점)
image = cv2.circle(image.copy(), tuple(kp), 5, (255, 0, 0), 10)
# 현재 키포인트에 점을 찍음
image = cv2.putText(image.copy(), f" {keypoints_classes_ids2names[idx]}", tuple(kp),
cv2.FONT_HERSHEY_SIMPLEX, 2, (255, 0, 0), 3, cv2.LINE_AA)
# 현재 키포인트가 Head인지 Tail인지 위에 선언한 dict에 해당하는 문자를 집어넣음
# 변환된 이미지만을 확인할 경우, 원본 이미지가 없을 것이므로 그대로 이미지 처리 끝냄
if image_original is None and keypoints_original is None:
plt.figure(figsize=(40, 40))
# 이미지를 그릴 차트 선언
plt.imshow(image)
# 위에서 bbox와 키포인트를 그린 이미지를 출력
else:
for bbox in bboxes_original:
# bbox = xyxy
start_point = (bbox[0], bbox[1])
# 사각형의 좌측 상단
end_point = (bbox[2], bbox[3])
# 사각형의 우측 하단
image_original = cv2.rectangle(image_original.copy(), start_point, end_point, (0, 255, 0), 2)
# 이미지에 bbox 좌표에 해당하는 사각형을 그림
for kpts in keypoints_original:
# keypoints : JSON 파일에 있는 keypoints 키의 값 (즉, keypoints 최상위 리스트)
# kpts : keypoints 내부의 각 리스트 (즉, 각 bbox의 키포인트 리스트)
for idx, kp in enumerate(kpts):
# kp : kpts 내부의 각 리스트 (즉, 키포인트 리스트 내부의 xy좌표쌍, 키포인트 점)
image_original = cv2.circle(image_original.copy(), tuple(kp), 5, (255, 0, 0), 10)
# 현재 키포인트에 점을 찍음
image_original = cv2.putText(image_original.copy(), f" {keypoints_classes_ids2names[idx]}", tuple(kp),
cv2.FONT_HERSHEY_SIMPLEX, 2, (255, 0, 0), 3, cv2.LINE_AA)
# 현재 키포인트가 Head인지 Tail인지 위에 선언한 dict에 해당하는 문자를 집어넣음
f, ax = plt.subplots(1, 2, figsize=(40, 20))
# 두 장의 이미지를 1행 2열, 즉 가로로 길게 보여주는 subplots 생성
ax[0].imshow(image_original)
# 첫번째 subplot에는 원본 이미지를 출력
ax[0].set_title("Original Image", fontsize=fontsize)
# 이미지 제목
ax[1].imshow(image)
# 두번째 subplot에는 변환이 완료된 이미지를 출력
ax[1].set_title("Transformed Image", fontsize=fontsize)
plt.show()
if __name__=="__main__":
visualize_image_show = True
visualize_targets_show = True
image = (batch[0][0].permute(1, 2, 0).numpy() * 255).astype(np.uint8)
# CustomDataset에서 Tensor로 변환했기 때문에 다시 plt에 사용할 수 있도록 numpy 행렬로 변경
# img, target, img_original, target_original = batch이므로, batch[0]는 img를 지칭
# batch[0][0]에 실제 이미지 행렬에 해당하는 텐서가 있을것 (batch[0][1]에는 dtype 등의 다른 정보가 있음)
bboxes = batch[1][0]['boxes'].detach().cpu().numpy().astype(np.int32).tolist()
# target['boxes']에 bbox 정보가 저장되어있으므로, 해당 키로 접근하여 bbox 정보를 획득
keypoints = []
for kpts in batch[1][0]['keypoints'].detach().cpu().numpy().astype(np.int32).tolist():
keypoints.append([kp[:2] for kp in kpts])
# 이미지 평면상 점들이 필요하므로, 3번째 요소로 들어있을 1을 제거
image_original = (batch[2][0].permute(1, 2, 0).numpy() * 255).astype(np.uint8)
# batch[2] : image_original
bboxes_original = batch[3][0]['boxes'].detach().cpu().numpy().astype(np.int32).tolist()
# batch[3] : target
keypoints_original = []
for kpts in batch[3][0]['keypoints'].detach().cpu().numpy().astype(np.int32).tolist():
keypoints_original.append([kp[:2] for kp in kpts])
if visualize_image_show:
visualize(image, bboxes, keypoints, image_original, bboxes_original, keypoints_original)
if visualize_targets_show and visualize_image_show == False:
print("Original targets: \n", batch[3], "\n\n")
# original targets: (줄바꿈) original targets dict 출력 (두줄 내림)
print("Transformed targets: \n", batch[1])
main.py
import torch
import torchvision
import albumentations as A
from engine import train_one_epoch, evaluate
from utils import collate_fn
from torch.utils.data import DataLoader
from Customdataset import KeypointDataset
from torchvision.models.detection import keypointrcnn_resnet50_fpn
from torchvision.models.detection.rpn import AnchorGenerator
def get_model(num_keypoints, weights_path=None):
# 필요한 모델에 대해 키포인트 개수를 정의하고, 기존 모델이 있는 경우 로드하는 편의함수
anchor_generator = AnchorGenerator(sizes=(32, 64, 128, 256, 512), aspect_ratios=(0.25, 0.5, 0.75, 1.0, 2.0, 3.0, 4.0))
# 여러 input size에 대해 feature map으로 넘어갈 때 적절한 비율 변환율을 도와주는 객체
model = keypointrcnn_resnet50_fpn(
pretrained=False, # 모델 자체는 pretrain된 것을 사용하지 않음
# 현재는 학습용 코드이기 때문에, pretrain 모델을 fine-tuning 하지않고 처음부터 가중치 업데이트를 하도록 설정
pretrained_backbone=True, # backbone만 pretrain된 것을 사용함
# backbone은 모델 설계상 이미 pretrain 됐을 것으로 상정했기 때문에
# 실제 가중치 없데이트가 주로 일어날 부분에 비해 pretrain 여부가 크게 상관있지 않음
num_classes=2, # 무조건 배경 클래스를 포함함
num_keypoints=num_keypoints,
rpn_anchor_generator=anchor_generator)
if weights_path: # 기존 모델이 있는 경우
state_dict = torch.load(weights_path)
model.load_state_dict(state_dict)
return model
train_transform = A.Compose([
A.Sequential([
A.RandomRotate90(p=1), # 랜덤 90도 회전
A.RandomBrightnessContrast(brightness_limit=0.3, contrast_limit=0.3, brightness_by_max=True,
always_apply=False, p=1) # 랜덤 밝기 및 대비 조정
], p=1)
], keypoint_params=A.KeypointParams(format='xy'),
bbox_params=A.BboxParams(format="pascal_voc", label_fields=['bboxes_labels']) # 키포인트의 형태를 x-y 순으로 지정
)
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
KEYPOINTS_FOLDER_TRAIN = "./keypoint_dataset/train/"
# train dataset이 있는 경로
train_dataset = KeypointDataset(KEYPOINTS_FOLDER_TRAIN, transform=train_transform)
train_dataloader = DataLoader(train_dataset, batch_size=6, shuffle=True, collate_fn=collate_fn)
model = get_model(num_keypoints=2)
model.to(device)
optimizer = torch.optim.SGD(model.parameters(), lr=0.001, momentum=0.9, weight_decay=0.0005)
# momentum : 이전에 가중치를 업데이트한 기울기를 얼마나 반영할 것인가?
# weight_decay : 가중치 감소율
lr_scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=5, gamma=0.3)
# stepLR : step_size epoch 마다 lr이 기준 lr * gamma 로 변경됨 -> 즉 5 epoch 마다 lr이 0.3배씩 줄어듬
num_epochs = 20
# 최대 학습 횟수
# 현재 engine에서 받아온 train_one_epoch 함수는 손실함수를 넣지 않아도 되도록 처리된 함수이므로,
# 손실함수의 정의 는 생략됨
for epoch in range(num_epochs):
train_one_epoch(model, optimizer, train_dataloader, device, epoch, print_freq=1000)
# 학습이 진행되는 함수
lr_scheduler.step()
# 학습 1 epoch가 끝날때마다 scheduler 역시 업데이트
if epoch % 10 == 0:
torch.save(model.state_dict(), f"./keypointsrcnn_weights_{epoch}.pth")
# 10 epochs마다 가중치 저장
torch.save(model.state_dict(), "./keypointsrcnn_weights_last.pth")
# 모든 epoch가 끝나면 last.pth까지 저장
'ComputerVision > [ObjectDetection]' 카테고리의 다른 글
MMdetection 설치 A-Z (0) | 2023.08.03 |
---|
[전처리] 사진 여러장처럼 보이게만들기(Augmentation)
학습데이터를 변형시켜 마치 다른 학습데이터처럼 만들기 : 한장의 사진으로 여러장의 학습데이터를 만들 수 있다.

import cv2
import matplotlib.pyplot as plt
import numpy as np
image = cv2.imread("image02.jpeg")
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
# #### rotation ####
# angle = 30
# h, w = image.shape[:2]
# center = (w//2, h//2)
# M = cv2.getRotationMatrix2D(center, angle, 1.0)
# # getRotationMatrix2D(중심 좌표, 회전 각도, 크기 변환 비율)
# rotated_img = cv2.warpAffine(image, M, (w, h))
# # warpAffine(원본 이미지, 회전 행렬, 이미지 크기)
# plt.imshow(image)
# plt.show()
# plt.imshow(rotated_img)
# plt.show()
# #### rotation ####
#### zoom ####
# h, w = image.shape[:2]
# zoom_scale = 4 # 이미지 확대/축소 배율
# enlarged_img = cv2.resize(image, (w*zoom_scale, h*zoom_scale), interpolation=cv2.INTER_CUBIC)
# # resize(원본 이미지, (최종 너비, 최종 높이), 이미지 보간 방법 (ex: cv2.INTER_CUBIC))
# center = [enlarged_img.shape[0] // 2, enlarged_img.shape[1] // 2]
# cut_half = 300
# zoomed_img = enlarged_img[center[0]-cut_half:center[0]+cut_half, center[1]-cut_half:center[1]+cut_half]
# plt.imshow(zoomed_img)
# plt.show()
#### zoom ####
#### shift ####
# shift = (0, 50)
# M = np.float32([
# [1, 0, shift[0]],
# [0, 1, shift[1]]
# ])
# # 이동 행렬: 좌측 2x2 -> 회전 행렬 (현재 단위행렬), 우측 1열: 이동 행렬 (x 변위, y 변위)
# shifted_img = cv2.warpAffine(image, M, (image.shape[1], image.shape[0]))
# plt.imshow(shifted_img)
# plt.show()
#### shift ####
#### flip ####
# flipped_img_updown = cv2.flip(image, 0) # 상하반전
# flipped_img_leftright = cv2.flip(image, 1) # 좌우반전
# flipped_img_lr_other = cv2.flip(image, -1) # 상하 & 좌우반전
# plt.imshow(image)
# plt.show()
# plt.imshow(flipped_img_updown)
# plt.show()
# plt.imshow(flipped_img_leftright)
# plt.show()
# plt.imshow(flipped_img_lr_other)
# plt.show()
#### flip ####
#### salt-and-pepper noise ####
# noise = np.zeros(image.shape, np.uint8) # uint8 = unsigned int 8-bit (부호 없는 1바이트 정수)
# cv2.randu(noise, 0, 255)
# black = noise < 30 # [True, True, False, False, False, ...] 형태의 Mask 생성
# white = noise > 225
# noise[black] = 0
# noise[white] = 255
# noise_b = noise[:, :, 0] # image.shape (h, w, c) -> h*w*c -> color channel : B, G, R
# noise_g = noise[:, :, 1]
# noise_r = noise[:, :, 2]
# noisy_img = cv2.merge([
# cv2.add(image[:, :, 0], noise_b),
# cv2.add(image[:, :, 1], noise_g),
# cv2.add(image[:, :, 2], noise_r)
# ])
# plt.imshow(image)
# plt.show()
# plt.imshow(noisy_img)
# plt.show()
#### salt-and-pepper noise ####
#### Gaussian Noise ####
# mean = 0
# var = 100
# sigma = var ** 0.5
# gauss = np.random.normal(mean, sigma, image.shape)
# gauss = gauss.astype('uint8')
# noisy_img = cv2.add(image, gauss)
# plt.imshow(noisy_img)
# plt.show()
#### Gaussian Noise ####
#### 색조 변경 ####
# RGB , HSV
# hsv_img = cv2.cvtColor(image, cv2.COLOR_RGB2HSV)
# hue_shift = 30
# hsv_img[:, :, 0] = (hsv_img[:, :, 0] + hue_shift) % 180
# rgb_img = cv2.cvtColor(hsv_img, cv2.COLOR_HSV2RGB)
# plt.imshow(image)
# plt.show()
# plt.imshow(rgb_img)
# plt.show()
#### 색조 변경 ####
#### 색상 변환 ####
# hsv_img = cv2.cvtColor(image, cv2.COLOR_RGB2HSV)
# # hsv[h, w, c]
# hsv_img[:, :, 0] += 50 # Hue -> 50도 증가
# hsv_img[:, :, 1] = np.uint8(hsv_img[:, :, 1] * 0.5) # 채도
# hsv_img[:, :, 2] = np.uint8(hsv_img[:, :, 2] * 1.5) # 밝기
# # imshow <- BGR / RGB 로 강제로 디코딩
# rgb_img = cv2.cvtColor(hsv_img, cv2.COLOR_HSV2RGB)
# plt.imshow(rgb_img)
# plt.show()
#### 색상 변환 ####
#### 이미지 크롭 ####
# x, y, w, h = 300, 300, 200, 200 # (100, 100) 좌표에서 (200 * 200) 크기로 자를 것임
# crop_img_wide = image[y-h:y+h, x-w:x+w] # (x, y) 를 중심으로 2w, 2h 크기로 자름
# crop_img_lt = image[y:y+h, x:x+w] # (x, y) 를 기점으로 (w, h) 만큼 오른쪽 아래로 간 크기로 자름
# plt.imshow(image)
# plt.show()
# plt.imshow(crop_img_wide)
# plt.show()
# plt.imshow(crop_img_lt)
# plt.show()
#### 이미지 크롭 ####
#### warpAffine ####
# x_diff = 50
# y_diff = 100
# h, w, c = image.shape
# M = np.float32([
# [1, 0, x_diff],
# [0, 1, y_diff]
# ]) # x축으로 50, y 축으로 100 이동하는 병진이동행렬
# shifted_img = cv2.warpAffine(image, M, (w, h))
# M = cv2.getRotationMatrix2D((w // 2, h // 2), 45, 1.0)
# rotated_img = cv2.warpAffine(image, M, (w, h))
# M = cv2.getRotationMatrix2D((w // 2, h // 2), 0, 0.5)
# halfed_img = cv2.warpAffine(image, M, (w, h), flags=cv2.INTER_AREA) # 가장자리를 검은색으로 칠한, 원본 이미지 크기와 같은 축소 이미지
# croped_img = halfed_img[h//2 - h//4 : h//2 + h//4,
# w//2 - w//4 : w//2 + w//4] # 가장자리를 잘라낸 이미지
# resized_img = cv2.resize(image, (w//2, h//2), interpolation=cv2.INTER_AREA)
# plt.imshow(image)
# plt.show()
# plt.imshow(shifted_img)
# plt.show()
# plt.imshow(rotated_img)
# plt.show()
# plt.imshow(resized_img)
# plt.show()
# plt.imshow(halfed_img)
# plt.show()
# plt.imshow(croped_img)
# plt.show()
#### warpAffine ####
#### blurring ####
# blur_img = cv2.GaussianBlur(image, (5, 5), 5)
# plt.imshow(blur_img)
# plt.show()
#### blurring ####
#### adaptive threshold ####
# img_gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
# thresh = cv2.adaptiveThreshold(img_gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 2)
# # ADAPTIVE_THRESH_MEAN_C: 적응형 임계값 처리, 임계값 기준을 평균치를 사용함
# # 인자 11: 블록 크기, 11x11 블록으로 이미지를 나눈 후 해당 영역
# plt.imshow(img_gray, 'gray')
# plt.show()
# plt.imshow(thresh, 'gray')
# plt.show()
#### adaptive threshold ####
#### 색온도 보정 ####
# org_img = image.copy()
# balance = [0.8, 0.7, 0.8]
# for i, value in enumerate(balance):
# if value != 1.0:
# org_img[:, :, i] = cv2.addWeighted(org_img[:,:,i], value, 0, 0, 0)
# # addWeighted: src에 대해 value만큼의 가중치로 색온도 조절
# plt.imshow(org_img)
# plt.show()
#### 색온도 보정 ####
#### 모션 블러 ####
# kernal_size = 15
# kernal_direction = np.zeros((kernal_size, kernal_size))
# kernal_direction[int((kernal_size)//2), :] = np.ones(kernal_size)
# kernal_direction /= kernal_size # 커널의 합이 1이 되도록
# kernal_matrix = cv2.getRotationMatrix2D((kernal_size/2, kernal_size/2), 45, 1)
# kernal = np.hstack((kernal_matrix[:, :2], [[0], [0]]))
# # kernal_matrix[:, :2] <- 회전 행렬에서 병진이동 벡터를 제외하고 회전 행렬 값만 가져옴
# # [[0],[0]] <- 병진이동 벡터 (이동 X)
# kernal = cv2.warpAffine(kernal_direction, kernal, (kernal_size, kernal_size))
# motion_blur_img = cv2.filter2D(image, -1, kernal)
# plt.imshow(motion_blur_img)
# plt.show()
#### 모션 블러 ####
#### 난수 노이즈 ####
# gray_img = cv2.imread('image02.jpeg', cv2.IMREAD_GRAYSCALE)
# h, w = gray_img.shape
# mean = 0
# var = 100
# sigma = var ** 0.5
# gaussian = np.random.normal(mean, sigma, (h, w))
# noisy_image = gray_img + gaussian.astype(np.uint8)
# # uint8 -> 0 ~ 255
# cv2.imshow("", noisy_image)
# cv2.waitKey()
#### 난수 노이즈 ####
#### 채도 조정 ####
# img = cv2.imread('image02.jpeg')
# org_img = img.copy()
# img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# saturation_factor = 1.5
# img_hsv[:, :, 1] = img_hsv[:, :, 1] * saturation_factor
# saturated_img = cv2.cvtColor(img_hsv, cv2.COLOR_HSV2BGR)
# cv2.imshow("", org_img)
# cv2.waitKey()
# cv2.imshow("", saturated_img)
# cv2.waitKey()
#### 채도 조정 ####
#### 밝기 조정 ####
# img = cv2.imread('image02.jpeg')
# org_img = img.copy()
# bright_diff = 50
# img_brighten = cv2.convertScaleAbs(img, alpha=1, beta=bright_diff)
# cv2.imshow("org", org_img)
# cv2.imshow("brighten", img_brighten)
# cv2.waitKey()
#### 밝기 조정 ####
#### 노이즈 제거 ####
# img_filtered = cv2.medianBlur(image, 5)
# plt.imshow(image)
# plt.show()
# plt.imshow(img_filtered)
# plt.show()
#### 노이즈 제거 ####
#### 히스토그램 균일화 ####
# img_gray = cv2.imread("image02.jpeg", cv2.IMREAD_GRAYSCALE)
# img_equalized = cv2.equalizeHist(img_gray)
# cv2.imshow("org", img_gray)
# cv2.imshow("hist_equal", img_equalized)
# cv2.waitKey()
#### 히스토그램 균일화 ####
'AI > [Preprocessing]' 카테고리의 다른 글
[전처리] 이미지 비율에 맞게 정사각형 만들기 (0) | 2023.06.15 |
---|---|
[전처리] 가져온 사진 정보 받기 (feat, xml) (1) | 2023.06.15 |
[전처리] 가져온 사진 정보 받기 (feat, json) (0) | 2023.06.14 |
[전처리] 폴더에 있는 사진 가져오기 (0) | 2023.06.14 |
[전처리] 범주형 데이터 전처리 (0) | 2023.06.06 |
[전처리] 이미지 비율에 맞게 정사각형 만들기
일반적으로 정사각형으로 만들면 화면비율이 깨짐
그런걸 방지하기 위해서 남는 부분은 다른 색으로 칠해버림

import matplotlib.pylab as plt
from PIL import Image
def expend2square(pil_img, background_color) : # 배경이미지 크기계산
width, heigth = pil_img.size
if width == heigth : # 이미 정사각형
return pil_img
elif width > heigth : # 너비가 > 높이인 경우
result = Image.new(pil_img.mode, (width, width), background_color)
result.paste(pil_img, (0, (width - heigth) // 2)) # x 좌표는 0, y 좌표는 이미지 중앙에 이미지 붙임
return result
else : # 높이가 > 너비인 경우
result = Image.new(pil_img.mode, (heigth, heigth), background_color)
result.paste(pil_img, ((heigth - width) //2,0)) # x 좌표는 이미지 중앙, y 좌표는 0 에 이미지 붙임
return result
def resize_with_padding(pil_img, new_size, background_color) : # 남는부분에 색칠하기
img = expend2square(pil_img, background_color)
img = img.resize((new_size[0], new_size[1]), Image.ANTIALIAS)
return img
img = Image.open("./image01.jpeg")
img_new = resize_with_padding(img, (300,300), (0,0,255)) # 300, 300 : 사진 크기 # 0,0,255 : RGB
plt.imshow(img)
plt.show()
plt.imshow(img_new)
plt.show()
'AI > [Preprocessing]' 카테고리의 다른 글
[전처리] 사진 여러장처럼 보이게만들기(Augmentation) (0) | 2023.06.16 |
---|---|
[전처리] 가져온 사진 정보 받기 (feat, xml) (1) | 2023.06.15 |
[전처리] 가져온 사진 정보 받기 (feat, json) (0) | 2023.06.14 |
[전처리] 폴더에 있는 사진 가져오기 (0) | 2023.06.14 |
[전처리] 범주형 데이터 전처리 (0) | 2023.06.06 |
[전처리] 가져온 사진 정보 받기 (feat, xml)
XML은 Extensible Markup Language의 약어로, 데이터를 저장하고 전송하는 데 사용되는 마크업 언어입니다.
HTML과 매우 유사하 지만, XML은 데이터와 문서 구조를 설명하는 데 중점을 둡니다.
XML은 텍스트 기반 형식이며, 데이터와 그 구조를 기술하는 데 사용할 수 있는 여러가지 태그와 속성을 제공합니다. 데이터는 요소(element)라고도 부르는 태그를 사용하여 표시되며, 요소 는 속성(attribute)과 값(value)을 가질 수 있습니다.
XML은 데이터를 계층 구조로 구성할 수 있으므로, 다양한 소프트웨어 시스템 간에 데이터를 교환하는 데 매우 유용합니다. 또한, XML은 데이터의 검증 및 검색이 용이하며, 대부분의 프로그래밍 언어에서 XML 파 서를 지원하므로 데이터를 쉽게 처리할 수 있습니다.
import os
import cv2
import matplotlib.pylab as plt
from xml.etree.ElementTree import parse
def xml_read(xml_path) :
root = parse(xml_path).getroot()
image_info = root.findall("image")
for image in image_info :
bbox = image.findall('box')
# <image id="0" name="01.jpg" width="640" height="480">
# image width height
image_width = image.attrib['width']
image_heigth = image.attrib['height']
# image name and path
image_name = image.attrib['name']
image_name = os.path.join("./data/", image_name)
# image read
image = cv2.imread(image_name)
# image BGR -> RGB
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
for box_info in bbox :
label = box_info.attrib['label']
# 값 -> string 타입
xtl = box_info.attrib['xtl']
ytl = box_info.attrib['ytl']
xbr = box_info.attrib['xbr']
ybr = box_info.attrib['ybr']
# 소수점이 포함이라 바로 int 값 변환 불가 하여 float 변환
xtl_f = float(xtl)
ytl_f = float(ytl)
xbr_f = float(xbr)
ybr_f = float(ybr)
# float -> int 변환
xtl_i = int(xtl_f)
ytl_i = int(ytl_f)
xbr_i = int(xbr_f)
ybr_i = int(ybr_f)
print(xtl_i, ytl_i, xbr_i, ybr_i, label)
### xtl="468.94" ytl="92.01" xbr="640.00" ybr="340.46"
### 이미지 시각화
image = cv2.rectangle(image, (xtl_i, ytl_i), (xbr_i, ybr_i), (0,255,0), 2)
### 라벨 추가
image = cv2.putText(image, label, (xtl_i, ytl_i-10),
cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 255), 2, cv2.LINE_AA)
plt.imshow(image)
plt.show()
xml_read("./data/annotations.xml")

xml to yolo format 변경하기
import os
import cv2
import matplotlib.pylab as plt
from xml.etree.ElementTree import parse
label_number_dict = {'cat':0, 'dog':1}
def xml_read(xml_path) :
root = parse(xml_path).getroot()
image_info = root.findall("image")
for image in image_info :
bbox = image.findall('box')
# <image id="0" name="01.jpg" width="640" height="480">
# image width height
image_width = image.attrib['width']
image_heigth = image.attrib['height']
# image name and path
image_name = image.attrib['name']
image_name_temp = image_name
image_name = os.path.join("./data/", image_name)
# image read
image = cv2.imread(image_name)
# image BGR -> RGB
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
for box_info in bbox :
label = box_info.attrib['label']
# 값 -> string 타입
xtl = box_info.attrib['xtl']
ytl = box_info.attrib['ytl']
xbr = box_info.attrib['xbr']
ybr = box_info.attrib['ybr']
# 소수점이 포함이라 바로 int 값 변환 불가 하여 float 변환
xtl_f = float(xtl)
ytl_f = float(ytl)
xbr_f = float(xbr)
ybr_f = float(ybr)
# float -> int 변환
x1_i = int(xtl_f)
y1_i = int(ytl_f)
x2_i = int(xbr_f)
y2_i = int(ybr_f)
### xtl="468.94" ytl="92.01" xbr="640.00" ybr="340.46"
# 이미지 사이즈가 필요 위에 있는 image_width, image_heigth 경우는 string 타입 형변환 필요 int
img_width_i = int(image_width)
img_height_i = int(image_heigth)
# Pascal_xyxy to YOlO center_x center_y yolo_w yolo_h
center_x = ((x2_i + x1_i)/(2*img_width_i))
center_y = ((y2_i + y1_i)/(2*img_height_i))
yolo_w = (x2_i - x1_i)/img_width_i
yolo_h = (y2_i - y1_i)/img_height_i
# file_name
image_name_temp = image_name_temp.replace('.jpg', '')
# label cat, dog -> 0, 1 로 변경하기
label_number = label_number_dict[label]
print("Pascal_xyxy to YOLO >> ", label_number,center_x, center_y, yolo_w, yolo_h)
# 텍스트로 저장하기
with open(f"{image_name_temp}.txt", "a") as f:
f.write(f"{label_number} {center_x} {center_y} {yolo_w} {yolo_h} \n")
xml_read("./data/annotations.xml")
Pascal_xyxy to YOLO >> 1 / 0.865625 / 0.45 / 0.26875 / 0.5166666666666667
Pascal_xyxy to YOLO >> 0 / 0.16171875 / 0.6041666666666666 / 0.3140625 / 0.44583333333333336
'AI > [Preprocessing]' 카테고리의 다른 글
[전처리] 사진 여러장처럼 보이게만들기(Augmentation) (0) | 2023.06.16 |
---|---|
[전처리] 이미지 비율에 맞게 정사각형 만들기 (0) | 2023.06.15 |
[전처리] 가져온 사진 정보 받기 (feat, json) (0) | 2023.06.14 |
[전처리] 폴더에 있는 사진 가져오기 (0) | 2023.06.14 |
[전처리] 범주형 데이터 전처리 (0) | 2023.06.06 |
[전처리] 가져온 사진 정보 받기 (feat, json)
JSON(JavaScript Object Notation)은 경량의 데이터 교환 형식 입니다.
JSON은 사람이 읽고 쓰기에 용이하고, 기계가 분석하고 생성 하기도 쉬워 많이 사용됩니다.
특히 웹에서 데이터를 주고받을 때 많이 사용되며, 대부분의 프로그래밍 언어에서 JSON 형식을 다룰 수 있습니다.
JSON은 키-값 쌍으로 이루어진 데이터 오브젝트를 저장합니다. 키(key)는 문자열이며, 값(value)은 문자열, 숫자, 불리언, 배열, 객체 등이 될 수 있습니다. 이러한 데이터 오브젝트들은 중첩될 수 있어 복잡한 데이터도 표현할 수 있습니다.
import json
# json 파일을 가져와야합니다.
json_data_path ="./data/instances_default.json"
with open(json_data_path, 'r', encoding="utf-8") as j : # 'r' read
json_data = json.load(j)
print(f"json type : {type(json_data)}")
print("json_data : ", json_data ) # 키, 밸류로 반환

다차원 딕셔너리 형태라 원하는 정보를 위해선 한차원 더 들어가야합니다.
# 변수 선언
categories_info = json_data['categories']
# [{'id': 1, 'name': 'cat', 'supercategory': ''}, {'id': 2, 'name': 'dog', 'supercategory': ''}]
images_info = json_data['images']
# [{'id': 1, 'width': 640, 'height': 480, 'file_name': '01.jpg', 'license': 0, 'flickr_url': '', 'coco_url': '', 'date_captured': 0}]
위의 정보를 이용하여 이미지 시각화 실습
import json
import os
import cv2
import matplotlib.pylab as plt
# json_path 경로 지정
json_path = "./data/instances_default.json"
# json 읽기
with open(json_path, 'r', encoding='utf-8') as j : # 'r' : read
json_data = json.load(j)
category_info = json_data['categories']
images_info = json_data['images']
annotations_info = json_data['annotations']
# 라벨 딕셔너리 선언
label_dict = {1: "cat", 2:"dog"} # 0 은 배경임
for image_json in images_info :
print(image_json)
# {'id': 1, 'width': 640, 'height': 480, 'file_name': '01.jpg', 'license': 0, 'flickr_url': '', 'coco_url': '', 'date_captured': 0}
file_name = image_json['file_name']
image_path = os.path.join("./data/", file_name)
image_id = image_json['id']
print(image_path)
# ./data/01.jpg
# image read
image = cv2.imread(image_path)
# iamge BGR -> RGB
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
# bbox info
for anno_json in annotations_info :
if image_id == anno_json['image_id'] :
bbox = anno_json['bbox']
# 좌표 변수에 박스 좌표 저장 (int 형 변환 이유 : cv2.rectangle 좌표 값은 int 형태만 가능)
x = int(bbox[0])
y = int(bbox[1])
w = int(bbox[2])
h = int(bbox[3])
# 박스 좌표 확인
print("bbox 좌표 >> " , x, y, w, h)
# bbox 좌표 >> 468 92 171 248
# bbox 좌표 >> 3 183 200 214
# 박스 그리기
cv2.rectangle(image, (x,y), (x+w, y+h), (0,255,0),2)
# 라벨 표시
category_id = anno_json['category_id']
label_name = label_dict[category_id]
print(label_name)
# dog
# cat
image = cv2.putText(image, label_name, (x, y-10), # 위에 글자두려고 -10
cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 255), 2, cv2.LINE_AA)
plt.imshow(image)
plt.show()

json format -> Yolo format 으로 변경하고 텍스트 파일로 저장하기
import json
import os
import cv2
import matplotlib.pylab as plt
# json_path 경로 지정
json_path = "./data/instances_default.json"
# json 읽기
with open(json_path, 'r', encoding='utf-8') as j :
json_data = json.load(j)
category_info = json_data['categories']
images_info = json_data['images']
annotations_info = json_data['annotations']
# 라벨 딕셔너리 선언
# 0 -> cat , 1 -> dog
label_dict = {1: 0, 2: 1}
for image_json in images_info :
print(image_json)
file_name = image_json['file_name']
image_path = os.path.join("./data/", file_name)
image_id = image_json['id']
print(image_path)
print("file name ", file_name)
# image read
image = cv2.imread(image_path)
# iamge BGR -> RGB
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
# image size
img_height, img_width, img_channel = image.shape
# bbox info
for anno_json in annotations_info :
if image_id == anno_json['image_id'] :
bbox = anno_json['bbox']
# 좌표 변수에 박스 좌표 저장 (int 형 변환 이유 : cv2.rectangle 좌표 값은 int 형태만 가능)
x = int(bbox[0])
y = int(bbox[1])
w = int(bbox[2])
h = int(bbox[3])
# 박스 그리기
cv2.rectangle(image, (x,y), (x+w, y+h), (0,255,0),2)
# 라벨 표시
category_id = anno_json['category_id']
label_number = label_dict[category_id]
# xywh -> center_x, center_y, w, h 변경 하기
center_x = ((2*x + w)/(2*img_width))
center_y = ((2*y + h)/(2*img_height))
yolo_w = w/img_width
yolo_h = h/img_height
print("yolo 좌표 변경 값 >> ",label_number,center_x, center_y, yolo_w, yolo_h)
# 이미지 명과 라벨 파일 명이 동일해야합니다.
# 위에 file_name 경우는 01.jpg 우리가 필요한것은 01 이라는 이름 입니다.
#file_name_tmep = os.path.splitext(file_name)[0]
file_name_temp = file_name.replace(".jpg", "")
# 텍스트 파일 쓰기
with open(f"{file_name_temp}.txt", "a") as f: # "a" 는 덮어쓰기 말고 새로만듬
f.write(f"{label_number} {center_x} {center_y} {yolo_w} {yolo_h} \n")
'AI > [Preprocessing]' 카테고리의 다른 글
[전처리] 이미지 비율에 맞게 정사각형 만들기 (0) | 2023.06.15 |
---|---|
[전처리] 가져온 사진 정보 받기 (feat, xml) (1) | 2023.06.15 |
[전처리] 폴더에 있는 사진 가져오기 (0) | 2023.06.14 |
[전처리] 범주형 데이터 전처리 (0) | 2023.06.06 |
[전처리] 손글씨 데이터 PCA 적용예시 (1) | 2023.06.06 |
[전처리] 폴더에 있는 사진 가져오기
학습을 위해 대량의 사진을 가져오기 위한 코드
일반적으로 사진을 그냥 막 가져와버리면 정렬이 제대로 안됨
우선 사과라는 폴더안에 있는 사진들을 가져오고 싶을때
# os listdir
import os
# 이미지가 저장된 디렉토리 경로
img_dir = './사과/'
# 디렉토리 내 모든 파일 목록 가져오기
file_list = os.listdir(img_dir)
print(file_list)
# 단점 정렬 되지 않습니다.

sorted를 써도 마찬가지
# 만약 정렬 하고 싶다면 sort 함수 사용
# os listdir
import os
# 이미지가 저장된 디렉토리 경로
img_dir = './사과/'
# 디렉토리 내 모든 파일 목록 가져오기
file_list = sorted(os.listdir(img_dir))
print(file_list)

import glob
import os
file_list = glob.glob(os.path.join("./사과/", "*.jpg"))
print(file_list)
# 을 활용해야 제대로 정렬된 상태로 가져옴
폴더안의 폴더도 for문으로 가능함
def get_img_paths(root_path): # 하위에 있는 경로 모두 탐색
file_paths = []
for (path, dir, files) in os.walk(root_path):
for file in files:
ext = os.path.splitext(file)[-1].lower()
formats = ['.bmp', '.jpg', '.jpeg', '.png', '.tif', '.tiff', '.dng']
if ext in formats:
file_path = os.path.join(path, file)
file_paths.append(file_path)
return file_paths
file_paths = get_img_paths("./사과/")
print(file_paths)
# 정렬 하고 싶다면 natsort.natsorted 이용
# file_paths_sort = natsort.natsorted(file_paths)
# print(file_list_sort)
'AI > [Preprocessing]' 카테고리의 다른 글
[전처리] 이미지 비율에 맞게 정사각형 만들기 (0) | 2023.06.15 |
---|---|
[전처리] 가져온 사진 정보 받기 (feat, xml) (1) | 2023.06.15 |
[전처리] 가져온 사진 정보 받기 (feat, json) (0) | 2023.06.14 |
[전처리] 범주형 데이터 전처리 (0) | 2023.06.06 |
[전처리] 손글씨 데이터 PCA 적용예시 (1) | 2023.06.06 |
[CV] 영상 기본 세팅 6 (특징점기반 추적 feat, ORB + 불필요 특징점 제거2)
특징점 검출 알고리즘은 컴퓨터 비전 및 이미지 처리에서 주요한 역할을 합니다.
ORB (Oriented FAST and Rotated BRIEF):
1. FAST(FeaturesfromAcceleratedSegmentTest)특징점검출기와BRIEF(BinaryRobustIndependent Elementary Features) 기술자의 조합입니다.
2. FAST를 사용하여 빠르게 특징점을 검출하고, BRIEF를 사용하여 특징점 주변의 특징을 설명합니다.
3. 회전에 불변한 특징점 검출 및 설명을 제공합니다.
4. ORB는 SIFT 및 SURF와 비교적 더 빠르지만, 일반적으로 덜 정확한 결과를 제공합니다.
import cv2
# 동영상 파일 열기
cap = cv2.VideoCapture("MS/CV/0612 객체탐지,추적/data/vtest.avi")
# ORB 객체 생성
orb = cv2.ORB_create()
while True:
# 프레임 읽기
ret, frame = cap.read()
if not ret:
break
# 그레이스케일로 변환
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 특징점 검출
keypoints = orb.detect(gray, None)
# 특징점 그리기
frame = cv2.drawKeypoints(frame, keypoints, None, (0, 150, 220), flags=0)
# 출력
cv2.imshow("ORB", frame)
if cv2.waitKey(30) & 0xFF == ord("q"):
break
cap.release()
cv2.destroyAllWindows()
를 쓰면 불필요한 특징점도 많이 나온다.
Mask를 활용하여 특징점 제거하기 2

import cv2
import numpy as np
# 동영상 파일 읽기
cap = cv2.VideoCapture("MS/CV/0612 객체탐지,추적/data/vtest.avi")
# ORB 객체 생성
orb = cv2.ORB_create()
# 특징점 최소 크기 설정
min_keypoint_size = 10
# 중복 특징점 제거 기준거리
duplicate_threshold = 10
while True:
# 프레임 읽기
ret, frame = cap.read()
if not ret:
break
# 그레이스케일로 변환
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 특징점 검출
keypoints = orb.detect(gray, None)
# 특징점 크기가 일정 크기 이상인 것만 남기기
keypoints = [kp for kp in keypoints if kp.size > min_keypoint_size] # 리스트 컴프리헨션(파이썬문법)
# 중복된 특징점 제거
mask = np.ones(len(keypoints), dtype=bool) # 1차원 배열
for i, kp1 in enumerate(keypoints):
if mask[i]:
for j, kp2 in enumerate(keypoints[i + 1:]):
if (
mask[ i + j + 1]
and np.linalg.norm(np.array(kp1.pt) - np.array(kp2.pt)) < duplicate_threshold # .pt : OpenCV의 KeyPoint 객체의 속성중 하나
):
mask[ i + j + 1] = False
# kp1.pt와 kp2.pt는 각각 두 개의 키포인트 객체인 kp1과 kp2의 위치 좌표를 나타냅니다.
"""
먼저, mask라는 길이가 keypoints의 길이와 동일한 불리언 배열을 생성합니다. 이 배열은 모든 원소를 True로 초기 화합니다.
그런 다음, keypoints 리스트를 반복하면서 현재 키포인트와 나머지 키포인트들 간의 거리를 계산하여 중복된 키포 인트를 확인합니다.
중복된 키포인트인 경우에는 해당 키포인트에 해당하는 mask의 원소를 False로 설정합니다.
마지막으로, mask를 기반으로 중복되지 않은 키포인트들만을 새로운 리스트로 필터링하여 keypoints를 업데이트 합니다.
이를 통해 중복된 특징점을 제거하고 유니크한 특징점만을 남기는 작업을 수행합니다.
"""
keypoints = [kp for i, kp in enumerate(keypoints) if mask[i]]
# 특징점 그리기
frame = cv2.drawKeypoints(frame, keypoints, None, (0, 200, 150), flags=0)
cv2.imshow("ORB", frame)
# 'q'를 누르면 종료
if cv2.waitKey(60) == ord('q'):
break
# 해제
cap.release()
cv2.destroyAllWindows()
'ComputerVision > [CV]' 카테고리의 다른 글
컴퓨터비전(CV) 공부 사이트 모음 (0) | 2024.03.18 |
---|---|
[CV] 영상 기본 세팅 5 (특징점기반 추적 feat, sift + 불필요 특징점 제거1) (0) | 2023.06.12 |
[CV] 영상 기본 세팅 4 (특징점기반 추적 feat, kalman) (1) | 2023.06.12 |
[CV] 영상 기본 세팅 3 (filter이해하기 feat, kalman) (1) | 2023.06.12 |
[CV] 영상 기본 세팅 2 (객체추적) (0) | 2023.06.12 |
[CV] 영상 기본 세팅 5 (특징점기반 추적 feat, sift + 불필요 특징점 제거1)
특징점 검출 알고리즘은 컴퓨터 비전 및 이미지 처리에서 주요한 역할을 합니다.
SIFT (Scale-Invariant Feature Transform):
1. 크기 및 회전에 불변한 특징점 검출 및 설명 알고리즘입니다.
2. 다양한 크기와 회전에서 특징점을 검출하고,특징점 주변의 지역 특징을 기술합니다.
3. 특징점 간의 일치를 찾기 위해 특징점 기술자를 사용합니다.
4. SIFT는 매우 강력한 특징점 검출 및 일치 알고리즘으로 알려져 있습니다.

import cv2
# 동영상 파읽 열기
cap = cv2.VideoCapture("MS/CV/0612 객체탐지,추적/data/slow_traffic_small.mp4")
# sift 객체 생성
sift = cv2.SIFT_create()
while True:
# 프레임 읽기
ret, frame = cap.read()
if not ret:
break
# 그레이스케일로 변환
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 특징점 검출
keypoints, descriptors = sift.detectAndCompute(gray, None)
# 특징점 그리기
frame = cv2.drawKeypoints(frame, keypoints, None,
flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
# 화면에 출력
cv2.imshow("frame", frame)
# 'q'를 누르면 종료
if cv2.waitKey(60) == ord('q'):
break
# 해제
cap.release()
cv2.destroyAllWindows()
개수제한 >>>
1. 이미지 대비 밝기 일정이상의 차이가 있을때만 보이게 하면서
2. 포인터를 수를 일정 수로 제한해서 포인터의 개수를 특정 객체에만 나타나게 설정

import cv2
cap = cv2.VideoCapture("MS/CV/0612 객체탐지,추적/data/slow_traffic_small.mp4")
# SIFT 객체 생성
sift = cv2.SIFT_create(contrastThreshold=0.02) # 이미지 대비의 밝기 차이
# 특지점 개수 제한 설정
max_keypoints = 100 # 100개의 특징점만 검출
while True:
# 프레임 읽기
ret, frame = cap.read()
if not ret:
break
# 그레이스케일로 변환
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 특징점 검출
keypoints, descriptors = sift.detectAndCompute(gray, None)
# 특징점 제한
if len(keypoints) > max_keypoints:
keypoints = sorted(keypoints, key=lambda x: -
x.response)[:max_keypoints]
"""
keypoints = sorted(keypoints, key=lambda x: -x.response):
keypoints 리스트를 x.response를 기준으로 내림차순으로 정렬
이는 키포인트의 response 값을 기준으로 정렬하겠다는 의미
response 값이 큰 키포인트일수록 우선순위를 가지게 됩니다
[:max_keypoints]: 정렬된 keypoints 리스트에서 처음부터 max_keypoints까지의 키포인트만 선택
이를 통해 최대 키포인트 수를 제한합니다.
"""
# 특징점 그리기
frame = cv2.drawKeypoints(frame, keypoints, None,
flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
# 프레임 출력
cv2.imshow("frame", frame)
# 'q'를 누르면 종료
if cv2.waitKey(60) == ord('q'):
break
# 해제
cap.release()
cv2.destroyAllWindows()
'ComputerVision > [CV]' 카테고리의 다른 글
컴퓨터비전(CV) 공부 사이트 모음 (0) | 2024.03.18 |
---|---|
[CV] 영상 기본 세팅 6 (특징점기반 추적 feat, ORB + 불필요 특징점 제거2) (0) | 2023.06.12 |
[CV] 영상 기본 세팅 4 (특징점기반 추적 feat, kalman) (1) | 2023.06.12 |
[CV] 영상 기본 세팅 3 (filter이해하기 feat, kalman) (1) | 2023.06.12 |
[CV] 영상 기본 세팅 2 (객체추적) (0) | 2023.06.12 |
[CV] 영상 기본 세팅 4 (특징점기반 추적 feat, kalman)
# 객체 추적 알고리즘 소개
움직이는 객체를 식별하고, 그 위치를 추적하는 방법을 의미합니다. 이를 통해 동영상이나 실시간 스트리밍 데 이터에서 객체의 움직임을 감지하고, 객체를 추적하는데 사용됩니다. 다음은 일반적으로 사용되는 몇 가지 객 체 추적 알고리즘입니다.
특징점 기반 추적 (Feature-based Tracking):
- 특징점기반 추적은객 체의 특징점을 검출하고, 이를 기반으로 객체를 추적합니다.
- SIFT (Scale-Invariant Feature Transform), SURF (Speeded-Up Robust Features), ORB (Oriented FAST and Rotated BRIEF) 등의 알고리즘을 사용하여 특징점을 검출합니다.
- 이 특징점들은 다음 프레임에서 찾아지며, 매칭을 통해 객체의 움직임을 추적합니다.
- 특징점의 일치도와 거리를 기반으로 가장 좋은매칭을 찾는 알고리즘을 사용합니다.
# 특징점 기반 추적 순서
특징점 기반 추적(Feature-based Tracking)에서 일반적으로 따르는 순서는 다음과 같습니다
초기화 단계:
1. 첫번째 프레임을 읽고 흑백 이미지로 변환합니다.
2. Shi-Tomasi 코너 검출기 또는 다른 특징 점검출방법을 사용하여 초기 추적 지점을선택합니다.
3. 추적할 특징점의 초기위치를 저장합니다.
import cv2
import numpy as np
# 동영상 파일 읽기
cap = cv2.VideoCapture("MS/CV/0612 객체탐지,추적/data/slow_traffic_small.mp4")
# 코너 검출기 파라미터 설정
feature_params = dict(maxCorners=100, qualityLevel=0.3,
minDistance=7, blockSize=7)
"""
maxCorners: 검출할 최대 특징점 수를 지정. 여기서는 최대 100개의 특징점을 검출하도록 설정
qualityLevel: 특징점으로 인정되기 위한 품질 기준. 0과 1 사이의 값,높을수록 특징점으로 인정되기 위한 조건이 엄격
minDistance: 검출된 특징점들 간의 최소 거리를 나타냄 이 거리보다 가까운 특징점은 제거
blockSize: 특징점 검출 시 사용되는 이웃 픽셀 블록의 크기. 특징점 검출 알고리즘에서 사용되는 계산에 영향을 미치는 요소
"""
# 광학 흐름 파라미터 설정
lk_params = dict(winSize=(30, 30), maxLevel=2, criteria=( # 알고리즘 중지기준
cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03)) # eps정확도가 criteria[0]보다 작을때까지 or count는 반복회수가 criteria[1]보다 작을때 까지 추적
"""
winSize=(30, 30): 이동 벡터를 추정하기 위해 사용되는 윈도우(window)의 크기
윈도우 크기는 광학 흐름 알고리즘에서 이웃 픽셀들 간의 관계를 분석하는 데 사용되는 영역의 크기를 조절
maxLevel=2: 피라미드 계층의 수
광학 흐름 알고리즘은 다단계의 피라미드 구조를 사용하여 이미지의 해상도를 다양하게 처리
"""
# 첫 프레임 읽기
ret, next_frame = cap.read()
prev_gray = cv2.cvtColor(next_frame, cv2.COLOR_BGR2GRAY)
# 초기 추적 지점 선택
prev_corners = cv2.goodFeaturesToTrack(prev_gray, mask=None, **feature_params)
prev_points = prev_corners.squeeze()
# 추적 결과를 표시하기위한 색상 설정
color = (0, 200, 0)
while True:
# 다음 프레임 읽기
ret, next_frame = cap.read()
if not ret:
break
# 현재 프레임 변환
gray = cv2.cvtColor(next_frame, cv2.COLOR_BGR2GRAY)
# 옵티컬 플로우 계산
next_points, status, err = cv2.calcOpticalFlowPyrLK(
prev_gray, gray, prev_points, None, **lk_params)
# 추적 결과를 좋은 포인트로 필터링
for i, (prev_point, next_point) in enumerate(zip(prev_points, next_points)):
x_prev, y_prev = prev_point.astype(np.int32)
x_next, y_next = next_point.astype(np.int32)
# cv2.line(prev_frame, (x_prev, y_prev), (x_next, y_next), color, 2)
cv2.circle(next_frame, (x_next, y_next), 3, color, 3)
# 화면에 출력
cv2.imshow("OpticalFlow-LK", next_frame)
# 다음 프레임을 위한 프레임과 포인트 저장
prev_gray = gray.copy()
prev_points = next_points
# 'q'를 누르면 종료
if cv2.waitKey(60) == ord('q'):
break
# 해제
cap.release()
cv2.destroyAllWindows()

'ComputerVision > [CV]' 카테고리의 다른 글
[CV] 영상 기본 세팅 6 (특징점기반 추적 feat, ORB + 불필요 특징점 제거2) (0) | 2023.06.12 |
---|---|
[CV] 영상 기본 세팅 5 (특징점기반 추적 feat, sift + 불필요 특징점 제거1) (0) | 2023.06.12 |
[CV] 영상 기본 세팅 3 (filter이해하기 feat, kalman) (1) | 2023.06.12 |
[CV] 영상 기본 세팅 2 (객체추적) (0) | 2023.06.12 |
[CV] 이미지 기본세팅 8 (확장 - dilation, 침식 - erosion) (0) | 2023.06.08 |
[CV] 영상 기본 세팅 3 (filter이해하기 feat, kalman)
# 객체 추적 알고리즘 소개
움직이는 객체를 식별하고, 그 위치를 추적하는 방법을 의미합니다. 이를 통해 동영상이나 실시간 스트리밍 데 이터에서 객체의 움직임을 감지하고, 객체를 추적하는데 사용됩니다. 다음은 일반적으로 사용되는 몇 가지 객 체 추적 알고리즘입니다.
칼만 필터 추적 (Kalman Filter Tracking):
1. 칼만필터는 상태추정에 사용되는 필터링 기술로, 객체추적에도 적용됩니다.
2. 초기예측과 실제관측을 기반으로 객체의 위치와 속도를 추정합니다.
3. 예측과 관측간의 오차를 고려하여 정확한 위치를 업데이트합니다.
4. 이를 통해 움직이는 객체의 경로를 추적하고, 예측을 통해 불확실성을 줄입니다.
측정 행렬(Measurement Matrix): 측정 행렬은 시스템의 상태를 측정값으로 변환하는 역할을 합니다. 측정 행렬은 상태 벡터와 측정 벡터 사이의 선형 변환을 정의합니다. 일반적으로 센서로부터 얻은 측정값을 상태 벡터의 선형 조합으로 표현하는 데 사용됩니다. 측정 행렬은 시스템의 동작과 측정 방식에 따라 결정되며, 변하지 않는 고정된 행렬입니다.
전이 행렬(Transition Matrix): 전이 행렬은 시스템의 상태를 현재 상태에서 다음 상태로 변환하는 역할을 합니다. 전이 행렬은 시스템의 동적 모델을 반영하여 상태 벡터를 현재 상태에서 다음 상태로 예측하는 데 사용됩니다. 전이 행렬은 시간에 따라 변할 수 있으며, 시스템의 동작을 모델링하는 데 사용되는 다른 행렬들과 연결되어 시스템의 상태 추정에 영향을 미칩니다.
import cv2
import numpy as np
# kalman filter
kalman = cv2.KalmanFilter(4,2) # 상태백터(위치와 속도 등)를 4차원으로 지정, 측정벡터(센서신호) 2차원으로 세팅)
# 측정 행렬을 설정합니다. 이 행렬은 측정 벡터를 상태 벡터로 변환하는 역할
kalman.measurementMatrix = np.array([[1,0,0,0],[0,1,0,0]],np.float32)
# 전이 행렬을 설정합니다. 이 행 렬은 시간에 따라 상태 벡터가 어떻게 변화하는지를 나타냄
kalman.transitionMatrix = np.array([[1,0,1,0],[0,1,0,1],[0,0,1,0],[0,0,0,1]],np.float32)
# 프로세스 잡음 공분산 행렬을 설정합니다. 이 값은 시스템의 불확실성을 모델링
kalman.processNoiseCov = np.array([[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]],np.float32) * 0.05
# 칼만 필터 추적 실습
# 영상 파일 열기
cap = cv2.VideoCapture("MS/데이터전처리/0612/data/slow_traffic_small.mp4")
# 첫 프레임에서 추적할 객체 선택
ret, frame = cap.read()
print(ret, frame) # 경로가 잘못된 경우 ret = False, frame = None / 정상일경우 ret = True, frame = 영상프레임
x, y, w, h = cv2.selectROI(frame, False, False)
"""
"Select Object": 객체를 선택할 때 표시될 창의 제목입니다.
frame: 이미지나 비디오 프레임을 나타내는 변수입니다.
False: 선택한 영역을 자동으로 크롭하지 않고, 선택한 영역의 좌표와 크기를 반환합니다.
False: 마우스 이벤트를 사용하여 객체의 영역을 선택할 수 있도록 합니다.
"""
print("선택한 박스의 좌표 >>", x, y, w, h)
# 객체 추적을 위한 초기 추정 위치 설정
# 객체의 x,y,x방향속도(초기0), y방향속도(초기0)로 지정 # 일단 속도를 알 수 없으니 0으로 초기화
kalman.statePre = np.array([[x],[y],[0],[0]],np.float32)
while True:
# 프레임 읽기
ret, frame = cap.read()
if not ret:
break
# 칼만 필터로 예측한 위치 계산
kalman.correct(np.array([[np.float32(x)+w/2],[np.float32(y)+h/2]]))
kalman.predict()
# 칼만 필터로 추정된 객체 위치
predicted_bbox = tuple(map(int, kalman.statePost[:2,0]))
"""
map(int, kalman.statePost[:2,0]): 상태 벡터의 값들을 int 함수를 사용하여 정수로 변환
map 함수는 시퀀스의 모든 요소에 함수를 적용하여 새로운 시퀀스를 생성
여기서는 상태 벡터의 값을 int 함수를 사용하여 정수로 변환
"""
# 추정된 위치에 사각형 그리기
cv2.rectangle(frame, (predicted_bbox[0]-w//2, predicted_bbox[1]-h//2),
(predicted_bbox[0]+w//2, predicted_bbox[1]+h//2),
(0,255,255), 2)
# 화면에 출력
cv2.imshow("frame", frame)
# 'q'를 누르면 종료
if cv2.waitKey(60) == ord('q'):
break
# 해제
cap.release()
cv2.destroyAllWindows()
import cv2
import numpy as np
# kalman filter
kalman = cv2.KalmanFilter(4,2)
kalman.measurementMatrix = np.array([[1,0,0,0],
[0,1,0,0]],np.float32)
kalman.transitionMatrix = np.array([[1,0,1,0],[0,1,0,1],[0,0,1,0],[0,0,0,1]],np.float32)
kalman.processNoiseCov = np.array([[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]],np.float32) * 0.05
# 칼만 필터 추적 실습
# 영상 파일 열기
cap = cv2.VideoCapture("MS/데이터전처리/0612/data/slow_traffic_small.mp4")
# 첫 프레임에서 추적할 객체 선택
ret, frame = cap.read()
print(ret, frame) # 경로가 잘못된 경우 ret = False, frame = None / 정상일경우 ret = True, frame = 영상프레임
x, y, w, h = cv2.selectROI(frame, False, False)
print("선택한 박스의 좌표 >>", x, y, w, h)
# 객체 추적을 위한 초기 추정 위치 설정
# 객체의 x,y,x방향속도(초기0), y방향속도(초기0)
kalman.statePre = np.array([[x],[y],[0],[0]],np.float32)
while True:
# 프레임 읽기
ret, frame = cap.read()
if not ret:
break
# 칼만 필터로 예측한 위치 계산
kalman.correct(np.array([[np.float32(x)+w/2],[np.float32(y)+h/2]]))
kalman.predict()
# 칼만 필터로 추정된 객체 위치
predicted_bbox = tuple(map(int, kalman.statePost[:2,0]))
# 추정된 위치에 사각형 그리기
cv2.rectangle(frame, (predicted_bbox[0]-w//2, predicted_bbox[1]-h//2),
(predicted_bbox[0]+w//2, predicted_bbox[1]+h//2),
(0,255,255), 2)
# 화면에 출력
cv2.imshow("frame", frame)
# 'q'를 누르면 종료
if cv2.waitKey(60) == ord('q'):
break
# 해제
cap.release()
cv2.destroyAllWindows()
'ComputerVision > [CV]' 카테고리의 다른 글
[CV] 영상 기본 세팅 5 (특징점기반 추적 feat, sift + 불필요 특징점 제거1) (0) | 2023.06.12 |
---|---|
[CV] 영상 기본 세팅 4 (특징점기반 추적 feat, kalman) (1) | 2023.06.12 |
[CV] 영상 기본 세팅 2 (객체추적) (0) | 2023.06.12 |
[CV] 이미지 기본세팅 8 (확장 - dilation, 침식 - erosion) (0) | 2023.06.08 |
[CV] 이미지 기본세팅 7 (필터효과) (0) | 2023.06.08 |
[CV] 영상 기본 세팅 2 (객체추적)
# 객체 추적 알고리즘 소개
움직이는 객체를 식별하고, 그 위치를 추적하는 방법을 의미합니다. 이를 통해 동영상이나 실시간 스트리밍 데 이터에서 객체의 움직임을 감지하고, 객체를 추적하는데 사용됩니다. 다음은 일반적으로 사용되는 몇 가지 객 체 추적 알고리즘입니다.
평균 이동 추적 (Mean Shift Tracking):
1. 평균 이동추적은 객체의 히스토그램을 기반으로 추적하는 알고리즘입니다.
2. 초기위치를 선택하고, 해당 위치의 픽셀분포를 히스토그램으로 계산합니다.
3. 다음 프레임에서 히스토그램 유사도를 측정하여 객체의 새로운 위치를 찾습니다.
4. 이 과정을 반복하여 객체의 움직임을 추적합니다.

우선 전체 코드
import cv2
# 평균 이동 추적을 위한 초기 사각형 설정
track_window = None # 객체의 위치 정보 저장할 변수
roi_hist = None # 히스토그램을 저장할 변수
trem_crit = (cv2.TERM_CRITERIA_EPS|cv2.TERM_CRITERIA_COUNT, 10,1) # 반복횟수 10
"""
cv2.TERM_CRITERIA_EPS: 반복 알고리즘의 정지 기준 중 하나로,
주어진 정지 기준 오차(epsilon)를 충족하는 경우 알고리즘을 중지합니다.
cv2.TERM_CRITERIA_COUNT: 반복 알고리즘의 정지 기준 중 하나로,
주어진 반복 횟수(count)를 충족하는 경우 알고리즘을 중지합니다.
따라서 cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT는 이 두 가지 정지 기준을 모두 사용하겠다는 의미입니다.
이러한 정지 기준을 설정한 후에는 알고리즘이 주어진 정지 기준에 도달하면 반복을 중지하게 됩니다.
또한, (10, 1)은 알고리즘의 최대 반복 횟수와 정지 기준 오차(epsilon) 값을 나타냅니다.
예를 들어, 여기서는 최대 10번의 반복과 1의 정지 기준 오차를 설정하였습니다.
따라서 알고리즘은 최대 10번 반복하거나 주어진 오차가 1 이하로 감소할 때까지 실행됩니다.
"""
# 영상 파일 열기
cap = cv2.VideoCapture("MS/데이터전처리/0612/data/slow_traffic_small.mp4")
# 첫 프레임에서 추적할 객체 선택
ret, frame = cap.read() # 영상 있냐없냐 T/F가 ret , Frame 저장
x, y, w, h = cv2.selectROI("selectROI", frame, False, False)
print("선택한 박스의 좌표 >>", x, y, w, h)
# 추적할 객체 초기 히스토그램 계산
roi = frame[y:y+h, x:x+w] # 관심구역
hsv_roi = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV) # (Hue 색상, Saturation 채도, Value 명도)
roi_hist = cv2.calcHist([hsv_roi], [0], None, [180], [0,180]) # 히스토그램 계산
cv2.normalize(roi_hist, roi_hist, 0, 255, cv2.NORM_MINMAX) # 히스토그램을 0부터 255로 정규화 (정확도 높일려고)
# 추적할 객체의 초기 윈도우 설정
track_window = (x, y, w, h)
# cv2.imshow("roi test", roi)
# cv2.waitKey(0)
# 평균 이동 추적
while True:
# 프레임 읽기
ret, frame = cap.read()
if not ret:
break
# 추적할 객체에 대한 채도 히스토그램 역투영계산
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
backproj = cv2.calcBackProject([hsv], [0], roi_hist, [0,180], 1)
"""
[hsv]: 역투영을 계산할 대상 이미지의 HSV 채널입니다. HSV 채널은 색상 정보를 갖고 있어 역투영에 활용됩니다.
[0]: 역투영에 사용할 채널 인덱스입니다. 여기서는 색상 채널(Hue)인 0번 인덱스를 사용합니다.
roi_hist: ROI(Region of Interest)의 히스토그램입니다. 이 히스토그램은 역투영에 사용됩니다.
[0,180]: 히스토그램의 범위를 나타냅니다. 여기서는 Hue 채널의 범위가 0부터 180까지로 설정되었습니다.
1: 확대 비율(scale)입니다. 픽셀의 값을 히스토그램의 값으로 나누어 정규화합니다.
"""
# 평균 이동으로 새 위치 검색
ret, track_window = cv2.meanShift(backproj, track_window, trem_crit)
# 검색된 새 위치에 사각형 그리기
x, y, w, h = track_window
print("새 위치 좌표 >>", x, y, w, h)
cv2.rectangle(frame, (x,y), (x+w, y+h), (0,255,0), 2)
"""
frame: 이미지 또는 비디오 프레임을 나타내는 변수입니다.
(x, y): 사각형의 왼쪽 위 모서리의 좌표입니다.
(x + w, y + h): 사각형의 오른쪽 아래 모서리의 좌표입니다. 여기서 w는 사각형의 너비, h는 사각형의 높이입니다.
(0, 255, 0): 사각형의 선 색상을 나타내는 RGB 값입니다. (R, G, B) 형식으로 표현됩니다. 여기서 (0, 255, 0)은 녹색을 나타냅니다.
2: 사각형 선의 두께를 나타냅니다.
"""
# 화면에 출력
cv2.imshow("backproj", backproj)
cv2.imshow("frame", frame)
# 'q'를 누르면 종료
if cv2.waitKey(60) == ord('q'):
exit()
# 해제
cap.release()
cv2.destroyAllWindows()


import cv2
# 평균 이동 추적을 위한 초기 사각형 설정
track_window = None # 객체의 위치 정보 저장할 변수
roi_hist = None # 히스토그램을 저장할 변수
trem_crit = (cv2.TERM_CRITERIA_EPS|cv2.TERM_CRITERIA_COUNT, 10,1) # 반복횟수 10
# 영상 파일 열기
cap = cv2.VideoCapture("MS/데이터전처리/0612/data/slow_traffic_small.mp4")
# 첫 프레임에서 추적할 객체 선택
ret, frame = cap.read()
x, y, w, h = cv2.selectROI("selectROI", frame, False, False)
print("선택한 박스의 좌표 >>", x, y, w, h)
# 추적할 객체 초기 히스토그램 계산
roi = frame[y:y+h, x:x+w]
hsv_roi = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV) # (Hue, Saturation, Value)
roi_hist = cv2.calcHist([hsv_roi], [0], None, [180], [0,180]) # 히스토그램 계산
cv2.normalize(roi_hist, roi_hist, 0, 255, cv2.NORM_MINMAX) # 히스토그램을 0부터 255로 정규화 (정확도 높일려고)
# 추적할 객체의 초기 윈도우 설정
track_window = (x, y, w, h)
# cv2.imshow("roi test", roi)
# cv2.waitKey(0)
# 평균 이동 추적
while True:
# 프레임 읽기
ret, frame = cap.read()
if not ret:
break
# 추적할 객체에 대한 채도 히스토그램 역투영계산
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
backproj = cv2.calcBackProject([hsv], [0], roi_hist, [0,180], 1)
# 평균 이동으로 새 위치 검색
ret, track_window = cv2.meanShift(backproj, track_window, trem_crit)
# 검색된 새 위치에 사각형 그리기
x, y, w, h = track_window
print("새 위치 좌표 >>", x, y, w, h)
cv2.rectangle(frame, (x,y), (x+w, y+h), (0,0,255), 2)
# 화면에 출력
cv2.imshow("backproj", backproj)
cv2.imshow("frame", frame)
# 'q'를 누르면 종료
if cv2.waitKey(60) == ord('q'):
break
# 해제
cap.release()
cv2.destroyAllWindows()
'ComputerVision > [CV]' 카테고리의 다른 글
[CV] 영상 기본 세팅 4 (특징점기반 추적 feat, kalman) (1) | 2023.06.12 |
---|---|
[CV] 영상 기본 세팅 3 (filter이해하기 feat, kalman) (1) | 2023.06.12 |
[CV] 이미지 기본세팅 8 (확장 - dilation, 침식 - erosion) (0) | 2023.06.08 |
[CV] 이미지 기본세팅 7 (필터효과) (0) | 2023.06.08 |
[CV] 이미지 기본세팅 6 (머신러닝 특성 만들기-flatten()) (0) | 2023.06.08 |
[CV] 이미지 기본세팅 8 (확장 - dilation, 침식 - erosion)
https://webnautes.tistory.com/1257
OpenCV Python 강좌 - 모폴로지 연산 (Morphological Operations)
OpenCV에서 제공하는 Erosion, Dilation, Opening, Closing 연산하는 함수들을 다룹니다. 보통 바이너리 이미지(Binary Image)에서 흰색으로 표현된 오브젝트의 형태를 개선하기 위해 사용됩니다. 마지막 업데
webnautes.tistory.com
을 먼저보고오는게 이해가 더 잘됨
1. threshold
경계면 구분을 원활하게 진행함
import cv2
import matplotlib.pyplot as plt
import numpy as np
image_path= "./data/a.png"
image = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
"""
230보다 큰 값은 모두 255로 설정되고 작은값은 0으로 (흰색으로 바뀜)
"""
_, mask = cv2.threshold(image, 230, 255, cv2.THRESH_BINARY_INV)
image_list = np.hstack([
image,
mask
])
plt.imshow(image_list, 'gray')
plt.show()

2. 확장 침식 실험 - 02
import cv2
import matplotlib.pyplot as plt
import numpy as np
image_path= "./data/a.png"
image = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
_, mask = cv2.threshold(image, 230, 255, cv2.THRESH_BINARY_INV)
kernel = np.ones((3,3), np.uint8)
dilation = cv2.dilate(mask, kernel, iterations=2) # iterations 반복횟수
erosion = cv2.erode(mask, kernel)
image_list = np.hstack([
image,
mask,
dilation, # 팽창
erosion # 침식
])
plt.imshow(image_list, 'gray')
plt.title('org img to mask, dilation, erosion')
plt.show()

image_path= "./data/a.png"
image = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
_, mask = cv2.threshold(image, 230, 255, cv2.THRESH_BINARY_INV)
kernel = np.ones((3,3), np.uint8)
dilation = cv2.dilate(mask, kernel, iterations=2) # iterations 반복횟수
erosion = cv2.erode(mask, kernel)
opening = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)
closing = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel)
image_list = np.hstack([
image,
mask,
dilation,
erosion,
opening,
closing
])
plt.imshow(image_list, 'gray')
plt.title('org img to mask, dilation, erosion, opening, closing')
plt.show()

3. 확장 침식 실험 - 03
image_path= "./data/a.png"
image = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
_, mask = cv2.threshold(image, 230, 255, cv2.THRESH_BINARY_INV)
kernel = np.ones((3,3), np.uint8)
dilation = cv2.dilate(mask, kernel, iterations=2) # iterations 반복횟수
erosion = cv2.erode(mask, kernel)
opening = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)
closing = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel)
mg = cv2.morphologyEx(mask, cv2.MORPH_GRADIENT, kernel) # 팽창과 침식의 차 / 경계, 윤곽선, 테두리 등을 추출에 주로 쓰임
th = cv2.morphologyEx(mask, cv2.MORPH_TOPHAT, kernel) # 이미지의 밝은 영역에서 뚜렷한 경계를 강조
image_list = np.hstack([
image,
mask,
dilation,
erosion,
opening,
closing
])
image_list_01 = np.hstack([
mg,
th
])
plt.imshow(image_list, 'gray')
plt.title('org img to mask, dilation, erosion, opening, closing')
plt.show()
plt.imshow(image_list_01, 'gray')
plt.title('org img to mg, th')
plt.show()

'ComputerVision > [CV]' 카테고리의 다른 글
[CV] 영상 기본 세팅 3 (filter이해하기 feat, kalman) (1) | 2023.06.12 |
---|---|
[CV] 영상 기본 세팅 2 (객체추적) (0) | 2023.06.12 |
[CV] 이미지 기본세팅 7 (필터효과) (0) | 2023.06.08 |
[CV] 이미지 기본세팅 6 (머신러닝 특성 만들기-flatten()) (0) | 2023.06.08 |
[CV] 이미지 기본세팅 4 (이미지 회전, 상하좌우반전) (1) | 2023.06.08 |
[CV] 이미지 기본세팅 7 (필터효과)
1. 커스텀 필터로 data폴더안에 있는 모든 .png파일 불러오기
import cv2
import matplotlib.pyplot as plt
import numpy as np
import os
import glob
image_path = "./data"
image_list = glob.glob(os.path.join(image_path, "*.png")) # data 폴더안에 .png를 모두 불러옴
for path in image_list :
print(path)
image = cv2.imread(path, 1)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
# custom filter
filter = np.array([[3,-2, -2 ], [-3, 7, -5], [5, -1, 0]])
"""
각각의 a, b, c는 필터의 가중치 값을 나타냅니다. 이 값은 이미지의 각 픽셀과 이웃한 픽셀 간의 계산에 사용됩니다.
필터는 이미지의 각 픽셀에 적용되며,
필터 윈도우 내의 픽셀 값과 필터의 가중치를 곱한 후 합산합니다.
"""
# custom filter 적용
custom_filter_img = cv2.filter2D(image, -1, filter) # -1 : 출력이미지의 뎁스를 입력이미지와 동일하게
plt.imshow(custom_filter_img)
plt.show()
2. 세피아 필터적용
image_path = "./data"
image_list = glob.glob(os.path.join(image_path, "*.png"))
for path in image_list :
print(path)
image = cv2.imread(path, 1)
# 효과필터 적용
filter_ = np.array([[0.272, 0.534, 0.131], [0.119,0.686, 0.168], [0.393, 0.769, 0.189]])
sepia_img = cv2.transform(image, filter_)
plt.imshow(sepia_img)
plt.show()
"""
cv2.transform 함수는 이미지의 전체적인 변환 작업에 사용되며,
cv2.filter2D 함수는 이미지 필터링 작업을 통해 픽셀 값을 변형하는 데 사용됩니다.
"""

3. 엠보스효과
import cv2
import matplotlib.pyplot as plt
import numpy as np
import os
import glob
image_path = "./data"
image_list = glob.glob(os.path.join(image_path, "*.png"))
for path in image_list :
print(path)
image = cv2.imread(path, 1)
# 엠보스 효과
filter_temp = np.array([[0, 1, 0], [0, 0, 0], [0, -1, 0]])
emboss_img = cv2.filter2D(image, -1, filter_temp)
emboss_img = emboss_img + 128
plt.imshow(emboss_img)
plt.show()

'ComputerVision > [CV]' 카테고리의 다른 글
[CV] 영상 기본 세팅 2 (객체추적) (0) | 2023.06.12 |
---|---|
[CV] 이미지 기본세팅 8 (확장 - dilation, 침식 - erosion) (0) | 2023.06.08 |
[CV] 이미지 기본세팅 6 (머신러닝 특성 만들기-flatten()) (0) | 2023.06.08 |
[CV] 이미지 기본세팅 4 (이미지 회전, 상하좌우반전) (1) | 2023.06.08 |
[CV] 이미지 기본세팅 3 (블러, 선명도, 대비) (2) | 2023.06.08 |
[CV] 이미지 기본세팅 6 (머신러닝 특성 만들기-flatten())
학습을 시키기위해 이미지 데이터를 1차원 벡터로 변환하는 과정
import cv2
import matplotlib.pyplot as plt
image_path = "./data/box.png"
### 경계선 찾기
# 1. 픽셀 강도의 중간값을 계산
image_gray = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
image_10x10 = cv2.resize(image_gray, (10,10)) # image 10x10 픽셀 크기로 변환
image_10x10.flatten() # 이미지 데이터를 1차원 벡터로 변환
plt.imshow(image_10x10, 'gray')
plt.show()

#### 머신러닝 특성 컬러 이미지 처리 결과
image_color = cv2.imread("./data/iamge01.png")
image_color = cv2.cvtColor(image_color, cv2.COLOR_BGR2RGB)
# image size 10 x 10
image_10x10_temp = cv2.resize(image_color, (10,10)) # image 10x10 픽셀 크기로 변환
a = image_10x10_temp.flatten() # 이미지 데이터를 1차원 백터로 변환
print(a, a.shape)
# image size 100 x 100
image_100x100_temp = cv2.resize(image_color, (100,100)) # image 10x10 픽셀 크기로 변환
b = image_255x255_temp.flatten() # 이미지 데이터를 1차원 백터로 변환
plt.imshow(image_10x10_temp)
plt.show()
plt.imshow(image_100x100_temp)
plt.show()



'ComputerVision > [CV]' 카테고리의 다른 글
[CV] 이미지 기본세팅 8 (확장 - dilation, 침식 - erosion) (0) | 2023.06.08 |
---|---|
[CV] 이미지 기본세팅 7 (필터효과) (0) | 2023.06.08 |
[CV] 이미지 기본세팅 4 (이미지 회전, 상하좌우반전) (1) | 2023.06.08 |
[CV] 이미지 기본세팅 3 (블러, 선명도, 대비) (2) | 2023.06.08 |
[CV] 이미지 기본세팅 2 (리사이징, 크롭) (0) | 2023.06.08 |
[CV] 이미지 기본세팅 4 (이미지 회전, 상하좌우반전)
1. 이미지회전
- cv2.rotate() 함수활용
- 옵션(이미지, cv2.ROTATE_{각도}_(COUNTER)CLOCKWISE)
import cv2
import matplotlib.pyplot as plt
import numpy as np
image_path = "./data/cat.png"
image = cv2.imread(image_path)
# RGB 타입으로 변경
image_org_ = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
# 이미지 회전
image_90 = cv2.rotate(image_org_, cv2.ROTATE_90_CLOCKWISE)
image_180 = cv2.rotate(image_org_, cv2.ROTATE_180)
image_270 = cv2.rotate(image_org_, cv2.ROTATE_90_COUNTERCLOCKWISE)
plt.imshow(image_90)
plt.show()
plt.imshow(image_180)
plt.show()
plt.imshow(image_270)
plt.show()


2. 상하좌우 반전
- cv2.flip()
- cv2.flip(이미지, 1 or 0) 1은 좌우반전, 0은 상하반전
import cv2
import matplotlib.pyplot as plt
import numpy as np
image_path = "./data/cat.png"
image = cv2.imread(image_path)
# RGB 타입으로 변경
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
# 1은 좌우 반전 / 0번은 상하 반전
dst_1 = cv2.flip(image, 1)
dst_2 = cv2.flip(image, 0)
plt.imshow(dst_1)
plt.show()
plt.imshow(dst_2)
plt.show()

'ComputerVision > [CV]' 카테고리의 다른 글
[CV] 이미지 기본세팅 7 (필터효과) (0) | 2023.06.08 |
---|---|
[CV] 이미지 기본세팅 6 (머신러닝 특성 만들기-flatten()) (0) | 2023.06.08 |
[CV] 이미지 기본세팅 3 (블러, 선명도, 대비) (2) | 2023.06.08 |
[CV] 이미지 기본세팅 2 (리사이징, 크롭) (0) | 2023.06.08 |
[CV] 이미지 기본세팅 1 (불러오기, 저장하기) (0) | 2023.06.07 |
[CV] 이미지 기본세팅 3 (블러, 선명도, 대비)
1. 블러처리 (이미지블러, 가우시안블러)
1. 이미지블러 cv2.blur() 함수활용
import cv2
import matplotlib.pyplot as plt
image_path = "./data/cat.png"
image = cv2.imread(image_path)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
image_blurry = cv2.blur(image, (5,5)) # cv2.blur() 를 활용함
# 33 55 77 # 블러강도를 나타냄
plt.imshow(image)
plt.show()
plt.imshow(image_blurry)
plt.show()

2. 가우시안블러 cv2.Gaussianblur() 함수활용
이걸 더 많이씀
import cv2
import matplotlib.pyplot as plt
import numpy as np
image_path = "./data/cat.png"
image = cv2.imread(image_path)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
image_g = cv2.GaussianBlur(image, (9,9), 0) # cv2.GaussianBlur() 를 사용함
# (9,9): 주변 커널수-> 세기조절이 됨
# 0 : 표준편차
plt.imshow(image)
plt.show()
plt.imshow(image_g)
plt.show()

2. 이미지 선명하게하기
import cv2
import matplotlib.pyplot as plt
import numpy as np
image_path = "./data/cat.png"
image = cv2.imread(image_path)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
kernel_ = np.array([[0,-1,0],
[-1,5,-1],
[0,-1,0]
])
image_sharp = cv2.filter2D(image, -1, kernel_)
plt.imshow(image)
plt.show()
plt.imshow(image_sharp)
plt.show()

3. 이미지 대비높이기
1 . 그레이스케일 일때 : 히스토그램 평활화 cv2.equalizeHist()에 BGR2Gray 활용 :
import cv2
import matplotlib.pyplot as plt
import numpy as np
image_path = "./data/cat.png"
image = cv2.imread(image_path)
image_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 단일 이미지에서만 적용가능!
image_enhanced = cv2.equalizeHist(image_gray)
plt.imshow(image_gray, 'gray')
plt.show()
plt.imshow(image_enhanced, 'gray')
plt.show()

2. 컬러일때 : RGB에 YUV를 추가함
import cv2
import matplotlib.pyplot as plt
import numpy as np
image_path = "./data/cat.png"
image = cv2.imread(image_path)
# RGB 타입으로 변경
image_org = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
# YUV 타입으로 변경
image_yuv = cv2.cvtColor(image, cv2.COLOR_BGR2YUV)
# 히스토그램 평활화 적용
image_yuv[:,:,0] = cv2.equalizeHist(image_yuv[:,:,0])
# YUV > RGB
image_rgb = cv2.cvtColor(image_yuv , cv2.COLOR_YUV2RGB)
plt.imshow(image_yuv)
plt.show()
plt.imshow(image_org)
plt.show()
plt.imshow(image_rgb)
plt.show()

4. 이진화(흑백)
import cv2
import matplotlib.pyplot as plt
import numpy as np
image_path = "./data/cat.png"
image = cv2.imread(image_path)
image_gray_01 = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 이미지 이진화
max_output_value = 255
neighborhood_size = 99
subtract_from_mean = 10
image_binarized = cv2.adaptiveThreshold(
image_gray_01,
max_output_value,
cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY, # cv2.THRESH_BINARY_INV(반전)
neighborhood_size,
subtract_from_mean
)
plt.imshow(image_binarized, 'gray')
plt.show()

'ComputerVision > [CV]' 카테고리의 다른 글
[CV] 이미지 기본세팅 6 (머신러닝 특성 만들기-flatten()) (0) | 2023.06.08 |
---|---|
[CV] 이미지 기본세팅 4 (이미지 회전, 상하좌우반전) (1) | 2023.06.08 |
[CV] 이미지 기본세팅 2 (리사이징, 크롭) (0) | 2023.06.08 |
[CV] 이미지 기본세팅 1 (불러오기, 저장하기) (0) | 2023.06.07 |
[CV] SAM - Segment Anything Model by META (0) | 2023.04.06 |
[CV] 이미지 기본세팅 2 (리사이징, 크롭)
1. 이미지 타입, 크기 확인하기
import cv2
image_path = "./data/cat.png"
# image read
image = cv2.imread(image_path)
# image 타입
image_type = type(image)
print("이미지 타입 >> " , image_type)
# 이미지 크기 확인
image_height, image_width, image_channel = image.shape
print(image_height, image_width, image_channel)
# 이미지 타입 >> <class 'numpy.ndarray'>
# 162 310 3
2. 이미지 리사이징
import cv2
import matplotlib.pyplot as plt
image_path = "./data/cat.png"
image = cv2.imread(image_path)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) # cv2로 불러오면 BGR을 RGB로 바꿔줘야함
# https://itcreator.tistory.com/141 에 적어둠
# 이미지 크기 조절
image_resize = cv2.resize(image, (244,244))
# 이미지 크기 확인
image_height_, image_width_, _ = image_resize.shape
# 원본 이미지
plt.imshow(image)
plt.show()

# 리사이즈 이미지
print(image_height_, image_width_)
# 244 244
plt.imshow(image_resize)
plt.show()

# 저장하기
import cv2
image_resize = cv2.cvtColor(image_resize, cv2.COLOR_BGR2RGB)
cv2.imwrite("./data/resize_image.png", image_resize) # cv2.imwrite로 저장하기
# True라고 뜨면 저장된거
3. 이미지 자르기(슬라이싱)
import cv2
import matplotlib.pyplot as plt
image_path = "./data/cat.png"
image = cv2.imread(image_path)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
image_cropped = image[10:,:200] # [행시작:행끝, 열시작:열끝]
plt.imshow(image)
plt.show()

plt.imshow(image_cropped)
plt.show()

3-1. 이미지자르기(좌표)
import cv2
import matplotlib.pyplot as plt
image_path = "./data/cat.png"
image = cv2.imread(image_path)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
x1, y1 = 50, 50 # 좌측 상단 모서리 좌표
x2, y2 = 150,150 # 우측 하단 모서리 좌표
cropped_image_test = image[y1:y2, x1:x2] # y가 먼저인 이유는 좌표평면에서 행렬의 행은 y값임
plt.imshow(cropped_image_test)
plt.show()

2. 변환하기
3. 리사이즈
4. 크롭 (슬라이싱,좌표)
'ComputerVision > [CV]' 카테고리의 다른 글
[CV] 이미지 기본세팅 4 (이미지 회전, 상하좌우반전) (1) | 2023.06.08 |
---|---|
[CV] 이미지 기본세팅 3 (블러, 선명도, 대비) (2) | 2023.06.08 |
[CV] 이미지 기본세팅 1 (불러오기, 저장하기) (0) | 2023.06.07 |
[CV] SAM - Segment Anything Model by META (0) | 2023.04.06 |
[CV] Pytorch VS tensorflow(keras) 점유율 비교 (0) | 2023.04.03 |
[CV] 이미지 기본세팅 1 (불러오기, 저장하기)
1. 이미지 불러오기 (png파일)
# !pip install opencv-python==4.5.5.64
import cv2
from matplotlib import pyplot as plt
img = cv2.imread("./data/cat.png") # cv2 라이브러리의 imread() 함수로 불러옴
# 색상의 문제 발생 -> BGR -> RGB
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
plt.imshow(img)
plt.show()

2. 이미지 저장하기(.npy)
넘파이를 이용하여 배열로 저장하기
.npy 파일로 저장하는 방법
import numpy as np
np.save("./data/image.npy", img) # 현재위치에 있는 data 폴더에 image.npy로 이미지만들기
# 만약에 해당폴더가 없으면 폴더생성하는 파이썬 코드
import os
def createDirectory(directory):
try:
if not os.path.exists(directory):
os.makedirs(directory)
except OSError:
print("Error: Failed to create the directory.")
2-1. 이미지 저장하기(PIL)
PIL은 간단한 이미지 처리와 변환 작업에 사용하기 좋음 / 컴퓨터 비전 작업에서는 OpenCV를 쓰는게 맞음
#!pip install Pillow
import numpy as np
from PIL import Image
# 이미지 불러오기
img = Image.open("./data/cat.png").convert('L') # 그레이 스케일 변환
print(img)
img_array = np.array(img)
np.save("./data/pil_image.npy", img_array) # .npy로 저장
img_array1 = np.load("./data/pil_image.npy") # .npy 불러오기
# 다시 PIL 이미지로 변환
img = Image.fromarray(np.uint8(img_array1)) # pil의 Image라이브러리 fromarray()로 변환
img.save("./data/image_numpy.png") # pil로 png로 변환
org_size = os.path.getsize("./data/cat.png")
np_save_size = os.path.getsize("./data/pil_image.npy")
pil_save_size = os.path.getsize("./data/image_numpy.png")
# 용량차이 확인하기
print(org_size, "bytes")
print(np_save_size, "bytes")
print(pil_save_size, "bytes")
# 원본 : 6468 bytes
# .npy로 저장 : 50348 bytes
# PIL를 활용하여 png로 저장 26808 bytes
3. 이미지 불러오기 (.npy)
img_data = np.load("./data/image.npy") # 넘파이의 load()로 불러옴
plt.imshow(img_data)
plt.show()

'ComputerVision > [CV]' 카테고리의 다른 글
[CV] 이미지 기본세팅 3 (블러, 선명도, 대비) (2) | 2023.06.08 |
---|---|
[CV] 이미지 기본세팅 2 (리사이징, 크롭) (0) | 2023.06.08 |
[CV] SAM - Segment Anything Model by META (0) | 2023.04.06 |
[CV] Pytorch VS tensorflow(keras) 점유율 비교 (0) | 2023.04.03 |
[CV] Computer Vision 관련 유용한 링크들 (0) | 2023.03.16 |