반응형

LinkedList.h

#pragma once

template<typename T>
class Link
{
	T value;
	Link<T>* link;
public:
	Link(void);
	Link(Link<T>* link);

	void SetLink(Link<T>* link);
	Link<T>* GetLink(void);
	void SetValue(T value);
	T GetValue(void);
};

template<typename T>
Link<T>::Link(void)
{
	link = nullptr;
}

template<typename T>
Link<T>::Link(Link<T>* link)
{
	this->link = link;
	this->value = 0;
}

template<typename T>
Link<T>* Link<T>::GetLink(void)
{
	return link;
}

template<typename T>
void Link<T>::SetLink(Link<T>* link)
{
	this->link = link;
}

template<typename T>
void Link<T>::SetValue(T value)
{
	this->value = value;
}

template<typename T>
T Link<T>::GetValue(void)
{
	return value;
}

main.cpp

#include "LinkedList.h"
#include <iostream>

int main(void)
{
	Link<int> intLink1 = new Link<int>();
	Link<int> intLink2 = new Link<int>();
	Link<int> intLink3 = new Link<int>();

	intLink1.SetValue(10);
	intLink2.SetValue(20);
	intLink3.SetValue(30);

	intLink1.SetLink(&intLink2);
	intLink2.SetLink(&intLink3);

	int i = 1;
	for (Link<int> link = intLink1; link.GetLink() != nullptr; link = *link.GetLink())
	{
		std::cout << i << "번째 value : " << link.GetValue() << std::endl;
		++i;
	}
	return 0;
}

실행결과

실행결과

C++로 구현한 LinkedList이다.

반응형
반응형

 

import cv2 as cv
import numpy as np

def DistanceTransform(img):
    assert type(img) is np.ndarray, 'Image was not a ndarray!'
    n_img = img.copy()
    _, n_img = cv.threshold(n_img,127,1,cv.THRESH_BINARY)
    
    # forward
    for i in range(1,n_img.shape[0]-1):
        for j in range(1,n_img.shape[1]-1):
            if n_img.item(i,j) == 1:
                if n_img.item(i-1,j) == 0 and n_img.item(i,j-1) == 0:
                    n_img.itemset(i,j,1)
                else:
                    value = np.min([n_img.item(i-1,j),n_img.item(i,j-1)]) + 1
                    n_img.itemset(i,j,value)

    #backward
    for i in range(1,n_img.shape[0]-1)[::-1]:
        for j in range(1,n_img.shape[1]-1)[::-1]:
            if n_img.item(i,j) >= 1:
                if n_img.item(i+1,j) == 0 and n_img.item(i,j+1) == 0:
                    n_img.itemset(i,j,1)
                else:
                    value = np.min([n_img.item(i+1,j),n_img.item(i,j+1)]) + 1
                    value = np.min([value,n_img.item(i,j)])
                    n_img.itemset(i,j,value)
    return n_img

if __name__ == "__main__":
    img = cv.imread('test.jpg')
    img = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
    new_img = DistanceTransform(img)
    new_img *= 5 # 픽셀값이 1씩 차이나면 잘 안보이므로 5를 곱해줌
    cv.imshow('roi',img)
    cv.imshow('res',new_img)
    cv.waitKey(0)
    cv.destroyAllWindows()

Distance Transform을 구현한 프로그램이다.

Distance Transform은 Binary Image에서 픽셀이 배경에서 멀어질수록,

픽셀이 점점 더 큰 값을 지니게 바꾸는 것이다.

4-연결성과 8-연결성으로 방법이 나뉘는데, 여기서는 4-연결성을 구현하였다.

Distance Transform 변환 모습

실행 결과는 다음과 같다.

Distance Transform 실행결과 [좌: 원본 이미지, 우: 결과 이미지]

 

반응형

'영상처리' 카테고리의 다른 글

Canny Edge Detection (Python) 수정  (0) 2022.06.23
K-MEANS Algorithm On Color Image  (0) 2021.04.09
Canny Edge Detection (Python)  (0) 2020.04.20
Image Rotation(Python)  (0) 2020.03.23
반응형
import cv2 as cv
import numpy as np
import random
import math
import copy

roi = cv.imread('sunflower.png') # 이미지 불러오기

k = 6 # 분류될 군집의 갯수

Z = [] # 각 군집의 대표값
X = [] # 샘플 집합. 여기서는 이미지픽셀
Z_xlist = [] # 각 군집에 해당되는 샘플을 저장할 리스트
prev_list = [] # 리스트의 이전상태를 기록할 리스트

for i in range(roi.shape[0]):
    for j in range(roi.shape[1]):
        x = (roi.item(i,j,0),roi.item(i,j,1),roi.item(i,j,2),(i,j)) # 이미지의 각 픽셀의 rgb값+이미지 좌표로 저장
        X.append(x) # 샘플리스트에 저장

checked = [] # 좌표 중복을 방지하기 위한 리스트
for i in range(k): # K개의 군집 초기화
    while True: # 랜덤하게 한 좌표를 뽑아서 Z를 초기화
        iy = random.randint(0,roi.shape[0]-1)
        ix = random.randint(0,roi.shape[1]-1)
        if (iy,ix) not in checked: # 체크한 좌표가 아니면 기록후 무한반복 탈출
            checked.append((iy,ix))
            break
    pos = checked[-1] # 방금 찾은 좌표로 설정
    value = ((roi.item(pos[0],pos[1],0),roi.item(pos[0],pos[1],1),roi.item(pos[0],pos[1],2)),(0,0,0))
    # Z 값은 방금 찾은 좌표의 rgb값 + 각 rgb의 총합(초기에는 0)
    Z.append(value)
    Z_xlist.append([]) # 각 군집에 해당되는 x는 아직 없음

while True:
    for x in X: # 모든 샘플에 대해 검사
        z_list = [] # 각 군집 대표값과 샘플의 유사성을 저장할 리스트
        for z in Z: # 각 군집 대표값과 유사성 측정후 저장
            dist = math.sqrt((x[0] - z[0][0])**2 + (x[1] - z[0][1])**2 + (x[2] - z[0][2])**2)
            # 유클리드 거리로 색의 유사성을 측정했으므로 0에 가까울수록 유사함.
            z_list.append(dist)
        idx = z_list.index(min(z_list)) # 최소값이 가장 유사한 군집
        z_value, z_sum = Z[idx] # 군집 대표값, 총합 가져옴
        z_sum = (z_sum[0] + x[0],z_sum[1] + x[1],z_sum[2] + x[2]) # x의 픽셀값을 총합에 더함
        Z[idx] = (z_value,z_sum) # 군집 갱신. 총합만 달라짐
        Z_xlist[idx].append(x) # 샘플을 해당 군집에 저장
    if prev_list == Z_xlist: # 탈출조건; 군집리스트가 변화가 없으면 알고리즘을 중단.
        break
    prev_list = copy.deepcopy(Z_xlist) # 군집 리스트변화를 측정하기 위해 현재 리스트 기록
    for idx, z in enumerate(Z): # 각 Z값 갱신
        z_value, z_sum = z
        z_value = (z_sum[0] / len(Z_xlist[idx]),
        z_sum[1] / len(Z_xlist[idx]),
        z_sum[2] / len(Z_xlist[idx])
        ) # 대표값은 각 채널값의 평균.
        z = (z_value, (0,0,0)) # 다시 샘플들을 검사해야하므로 총합은 0이고 대표값만 수정
    Z_xlist.clear() # 샘플리스트 초기화
    for i in range(k):
        Z_xlist.append([])

result = np.zeros((roi.shape[0],roi.shape[1],roi.shape[2]),dtype=np.uint8) # 결과이미지

for idx, xlist in enumerate(Z_xlist):
    rand = random.Random()
    rand.seed(idx*10) # 일정한 색 출력을 위해 시드 고정. 시드값은 K의 인덱스 * 10
    b = rand.randint(0,255)
    g = rand.randint(0,255)
    r = rand.randint(0,255)
    for x in xlist: # 해당 군집의 샘플의 위치를 알아내서 군집색으로 표시
        i, j = x[3] 
        result.itemset(i,j,0,b)
        result.itemset(i,j,1,g)
        result.itemset(i,j,2,r)

cv.imshow('roi',roi) # 기존 이미지
cv.imshow('res',result) # 군집화된 이미지
cv.waitKey(0)
cv.destroyAllWindows()

K-Means 알고리즘을 적용하여 컬러영상을 분할하는 프로그램이다.

6개의 군집으로 이미지 화소들을 분할한다.

 

결과 이미지[좌: 원본 이미지, 우: 결과 이미지]

반응형

'영상처리' 카테고리의 다른 글

Canny Edge Detection (Python) 수정  (0) 2022.06.23
Distance Transform  (0) 2021.04.09
Canny Edge Detection (Python)  (0) 2020.04.20
Image Rotation(Python)  (0) 2020.03.23

+ Recent posts