# pip install numpy
import numpy as np
x = np.arange(24) # 0~23까지의 데이터를 발생 
x
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
       17, 18, 19, 20, 21, 22, 23])
x.shape # 각 행에 1개의 스칼라 값이 있음 
(24,)

numpy array구조 익히기

x(24,)y(24,1)는 굉장히 다르다.

위와 아래의 결과값을 보면 차이가 있다.

인덱싱의 차이

y = x.reshape(24,1) # 각 행에 1개의 벡터값이 있음
y
array([[ 0],
       [ 1],
       [ 2],
       [ 3],
       [ 4],
       [ 5],
       [ 6],
       [ 7],
       [ 8],
       [ 9],
       [10],
       [11],
       [12],
       [13],
       [14],
       [15],
       [16],
       [17],
       [18],
       [19],
       [20],
       [21],
       [22],
       [23]])
x[0], y[0][0], y[1][0] # 인덱싱을 잘 봐보자
(0, 0, 1)

reshape

reshape함수를 통해 행과 열을 재배치 하거나, 차원을 높이거나 낮출 수도 있다.

x.reshape(12,-1) # -1: 열은 알아서 해달라는 의미
array([[ 0,  1],
       [ 2,  3],
       [ 4,  5],
       [ 6,  7],
       [ 8,  9],
       [10, 11],
       [12, 13],
       [14, 15],
       [16, 17],
       [18, 19],
       [20, 21],
       [22, 23]])
z=x.reshape(1,12,-1) # 차원 올리기
x[0],y[0],z[0]
(0,
 array([0]),
 array([[ 0,  1],
        [ 2,  3],
        [ 4,  5],
        [ 6,  7],
        [ 8,  9],
        [10, 11],
        [12, 13],
        [14, 15],
        [16, 17],
        [18, 19],
        [20, 21],
        [22, 23]]))
x1 = np.array([[100,5,0,100,5],[0,255,0,0,5]])
x2 = np.array([[100,50,0,100,2],[0,255,257,0,2]])

type(x1),type(x2) # numpy array 타입
(numpy.ndarray, numpy.ndarray)
img=[x1,x2] # tensor의 역할을 한다고 가정
type(img)
list
imgs = np.array(img)
type(imgs), imgs.dtype
(numpy.ndarray, dtype('int32'))
imgs+=50
imgs
array([[[150,  55,  50, 150,  55],
        [ 50, 305,  50,  50,  55]],

       [[150, 100,  50, 150,  52],
        [ 50, 305, 307,  50,  52]]])

8비트 숫자형 타입

  • int8 : -128 ~ 127

  • Uint8 : 0 ~ 255 (양수만 저장 가능)

RGB값을 표현하는 것이 목적이기 때문에 uint8로 변경

img=imgs.astype('uint8')
imgs.dtype, imgs
(dtype('int32'),
 array([[[150,  55,  50, 150,  55],
         [ 50, 305,  50,  50,  55]],
 
        [[150, 100,  50, 150,  52],
         [ 50, 305, 307,  50,  52]]]))
np.shape(x1), np.shape(imgs)
((2, 5), (2, 2, 5))

matplotlib

이미지 처리를 위한 모듈설치

#!pip install matplotlib
import matplotlib.pyplot as plt

plt.imshow(x1, cmap='gray') # 여러개의 플롯을 그리려면 서브플롯을 이용한다.
<matplotlib.image.AxesImage at 0x1c6390d95d0>

subplot(nrows, ncols, index, **kwargs)

  • nrows (정수): 서브플롯의 행(row) 수를 지정합니다.

  • ncols (정수): 서브플롯의 열(column) 수를 지정합니다.

  • index (정수 또는 튜플): 현재 서브플롯의 인덱스를 지정합니다. 인덱스는 1부터 시작하며, 왼쪽에서 오른쪽으로 순서대로 증가합니다. 튜플을 사용하여 여러 개의 인덱스를 지정할 수도 있습니다.

  • **kwargs (키워드 인자): 선택적인 키워드 인자를 추가로 지정할 수 있습니다. 이를 통해 서브플롯의 속성을 조정할 수 있습니다. 예를 들어, sharex=True를 사용하면 여러 서브플롯이 같은 x축을 공유하게 됩니다.

sample_cnt=5

for cnt, img in enumerate(imgs):
    cnt +=1
    plt.subplot(1,len(imgs[:sample_cnt]),cnt) # len(imgs) ==> np.shape(imgs)[0]으로써도 가능 
    plt.imshow(img, cmap='gray')

x1=[1,3,1,1,3,1,1,1,3,1]
x2=[1,3,1,1,3,7,15,1,13,100]

imgs=np.array([x1,x2])
imgs # 1차원 array는 이미지 구조 불가능(tensor가 아님) -> reshape가 필요한 이유

imgs.shape

# sample_cnt=5

# for cnt, img in enumerate(imgs):
#     cnt +=1
#     plt.subplot(1,len(imgs[:sample_cnt]),cnt) # len(imgs) ==> np.shape(imgs)[0]으로써도 가능 
#     plt.imshow(img, cmap='gray')
(2, 10)
imgs=imgs.reshape(2,2,-1) # tensor
imgs.shape
(2, 2, 5)
sample_cnt=5

for cnt, img in enumerate(imgs):
    cnt +=1 # 서브플롯의 인덱스가 1부터 시작한다.
    plt.subplot(1,len(imgs[:sample_cnt]),cnt) # len(imgs) ==> np.shape(imgs)[0]으로써도 가능 
    plt.imshow(img, cmap='gray')

y=np.random.normal(size=2500)
x=np.arange(len(y))

plt.bar(x,y)
<BarContainer object of 2500 artists>

plt.hist(y) # 데이터의 빈도수를 나타내는 히스토그램
(array([ 15.,  68., 199., 492., 624., 581., 346., 138.,  34.,   3.]),
 array([-3.2431813 , -2.56245007, -1.88171885, -1.20098762, -0.52025639,
         0.16047483,  0.84120606,  1.52193728,  2.20266851,  2.88339973,
         3.56413096]),
 <BarContainer object of 10 artists>)

np.random.normal : 정규분포 난수를 발생

img = y.reshape(50,50)

plt.imshow(img, cmap='gray')
<matplotlib.image.AxesImage at 0x1c63b7a95d0>

위의 그림을 노이즈 데이터라고 합니다. y라는 1차원 데이터를 2차원으로 reshape 하여 이미지를 처리

np.min(y), np.max(y) # 음수값이 나오게 됌
(-3.2431812969737743, 3.564130959526397)
#y[y<0]=0 # 0이하 값은 발생하지 않음. if문을 사용하지않음
y[y<0]=100 # NumPy 배열 y에서 값이 0보다 작은 요소를 선택하고,
            # 선택된 요소들에 대해 값을 100으로 변경하는 것을 의미
img = y.reshape(50,50)
plt.imshow(img,cmap='gray')
<matplotlib.image.AxesImage at 0x1c63b7a9e50>

for문보다 array를 사용하는 이유

코드의 가독성 뿐 아니라 내부의 속도도 차이가 난다.

a=np.arange(15).reshape(3,5)

for row,rowData in enumerate(a):
    for col,colData in enumerate(rowData):
        if colData<5:
            a[row][col]=50
            
a
array([[50, 50, 50, 50, 50],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])
a=np.arange(15).reshape(3,5)
[a<5]
[array([[ True,  True,  True,  True,  True],
        [False, False, False, False, False],
        [False, False, False, False, False]])]
a[a<5]=50
a
array([[50, 50, 50, 50, 50],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])

TODO : @(matrix) array.dot() 알아보기

Broadcast

서로 다른 shape를 가진 배열들 간에 연산을 수행하기 위해 자동으로 배열의 모양을 조정하는 기능

  1. 두 배열의 차원 수가 다르면, 차원 수가 더 큰 배열의 앞쪽에 크기가 1인 차원을 추가합니다.

  2. 두 배열의 크기가 어느 한 차원에서 일치하지 않으면, 크기가 1인 차원을 가진 배열을 더 큰 크기에 맞춰 늘립니다.

  3. 두 배열의 크기가 어느 한 차원에서 일치하지 않고, 두 배열의 크기가 1도 아니라면, 에러가 발생합니다.

a+100 # 스칼라 단위
array([[150, 150, 150, 150, 150],
       [105, 106, 107, 108, 109],
       [110, 111, 112, 113, 114]])
a+[1,100,1000,1000,1000] # 행 단위
array([[  51,  150, 1050, 1050, 1050],
       [   6,  106, 1007, 1008, 1009],
       [  11,  111, 1012, 1013, 1014]])
a
array([[50, 50, 50, 50, 50],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])
a[:,0]+50 # a의 모든 행의 0번 열에 +50
array([100,  55,  60])

이미지의 가장 하단, 이미지의 가장 상단, 우측, 좌측 등을 검은색으로 바꾸는 식의 작업에 활용

a[0,:]=0
a
array([[ 0,  0,  0,  0,  0],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])

hstack, vstack

subplot 대신에 array를 이어 붙여서 한번에 표현하기 위해 사용

vstack은 세로로 붙이고 hstack은 가로로 붙임

duckRGB = np.array([
[[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255]],
[[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255]],
[[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,229,153],[255,229,153],[255,229,153],[255,229,153],[255,229,153],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255]],
[[255,255,255],[255,255,255],[255,255,255],[255,229,153],[255,229,153],[255,229,153],[255,229,153],[255,229,153],[255,229,153],[255,229,153],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255]],
[[255,255,255],[255,255,255],[255,255,255],[255,153, 0],[255,229,153],[ 0, 0, 0],[255,229,153],[255,229,153],[255,229,153],[255,229,153],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255]],
[[255,255,255],[255,153, 0],[255,153, 0],[255,153, 0],[255,229,153],[255,229,153],[255,229,153],[255,229,153],[255,229,153],[255,229,153],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255]],
[[255,255,255],[255,255,255],[255,153, 0],[255,153, 0],[255,153, 0],[255,229,153],[255,229,153],[255,229,153],[255,229,153],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255]],
[[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,229,153],[255,229,153],[255,229,153],[255,229,153],[255,255,255],[255,229,153],[255,229,153],[255,229,153],[255,255,255],[255,229,153],[255,255,255],[255,255,255]],
[[255,255,255],[255,255,255],[255,255,255],[255,229,153],[255,229,153],[255,229,153],[255,229,153],[255,229,153],[255,229,153],[255,229,153],[255,229,153],[255,229,153],[ 0, 0, 0],[255,229,153],[255,255,255],[255,255,255]],
[[255,255,255],[255,255,255],[255,229,153],[255,229,153],[255,229,153],[255,229,153],[255,229,153],[ 0, 0, 0],[255,229,153],[255,229,153],[255,229,153],[ 0, 0, 0],[255,229,153],[255,229,153],[255,255,255],[255,255,255]],
[[255,255,255],[255,255,255],[255,229,153],[255,229,153],[255,229,153],[255,229,153],[255,229,153],[255,229,153],[ 0, 0, 0],[ 0, 0, 0],[ 0, 0, 0],[255,229,153],[255,229,153],[255,229,153],[255,255,255],[255,255,255]],
[[ 74,134,232],[ 74,134,232],[255,229,153],[255,229,153],[255,229,153],[255,229,153],[255,229,153],[255,229,153],[255,229,153],[255,229,153],[255,229,153],[255,229,153],[255,229,153],[255,229,153],[ 74,134,232],[ 74,134,232]],
[[ 74,134,232],[ 74,134,232],[ 74,134,232],[255,229,153],[255,229,153],[255,229,153],[255,229,153],[255,229,153],[255,229,153],[255,229,153],[255,229,153],[255,229,153],[255,229,153],[ 74,134,232],[ 74,134,232],[ 74,134,232]],
[[ 74,134,232],[ 74,134,232],[ 74,134,232],[ 74,134,232],[255,229,153],[255,229,153],[255,229,153],[255,229,153],[255,229,153],[255,229,153],[255,229,153],[255,229,153],[ 74,134,232],[ 74,134,232],[ 74,134,232],[ 74,134,232]],
[[ 74,134,232],[ 74,134,232],[ 74,134,232],[ 74,134,232],[ 74,134,232],[ 74,134,232],[ 74,134,232],[ 74,134,232],[ 74,134,232],[ 74,134,232],[ 74,134,232],[ 74,134,232],[ 74,134,232],[ 74,134,232],[ 74,134,232],[ 74,134,232]],
[[ 74,134,232],[ 74,134,232],[ 74,134,232],[ 74,134,232],[ 74,134,232],[ 74,134,232],[ 74,134,232],[ 74,134,232],[ 74,134,232],[ 74,134,232],[ 74,134,232],[ 74,134,232],[ 74,134,232],[ 74,134,232],[ 74,134,232],[ 74,134,232]],
], dtype=np.uint8)
duckRGB[:,:,:] == [255,255,255]
array([[[ True,  True,  True],
        [ True,  True,  True],
        [ True,  True,  True],
        [ True,  True,  True],
        [ True,  True,  True],
        [ True,  True,  True],
        [ True,  True,  True],
        [ True,  True,  True],
        [ True,  True,  True],
        [ True,  True,  True],
        [ True,  True,  True],
        [ True,  True,  True],
        [ True,  True,  True],
        [ True,  True,  True],
        [ True,  True,  True],
        [ True,  True,  True]],

       [[ True,  True,  True],
        [ True,  True,  True],
        [ True,  True,  True],
        [ True,  True,  True],
        [ True,  True,  True],
        [ True,  True,  True],
        [ True,  True,  True],
        [ True,  True,  True],
        [ True,  True,  True],
        [ True,  True,  True],
        [ True,  True,  True],
        [ True,  True,  True],
        [ True,  True,  True],
        [ True,  True,  True],
        [ True,  True,  True],
        [ True,  True,  True]],

       [[ True,  True,  True],
        [ True,  True,  True],
        [ True,  True,  True],
        [ True,  True,  True],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True,  True,  True],
        [ True,  True,  True],
        [ True,  True,  True],
        [ True,  True,  True],
        [ True,  True,  True],
        [ True,  True,  True],
        [ True,  True,  True]],

       [[ True,  True,  True],
        [ True,  True,  True],
        [ True,  True,  True],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True,  True,  True],
        [ True,  True,  True],
        [ True,  True,  True],
        [ True,  True,  True],
        [ True,  True,  True],
        [ True,  True,  True]],

       [[ True,  True,  True],
        [ True,  True,  True],
        [ True,  True,  True],
        [ True, False, False],
        [ True, False, False],
        [False, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True,  True,  True],
        [ True,  True,  True],
        [ True,  True,  True],
        [ True,  True,  True],
        [ True,  True,  True],
        [ True,  True,  True]],

       [[ True,  True,  True],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True,  True,  True],
        [ True,  True,  True],
        [ True,  True,  True],
        [ True,  True,  True],
        [ True,  True,  True],
        [ True,  True,  True]],

       [[ True,  True,  True],
        [ True,  True,  True],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True,  True,  True],
        [ True,  True,  True],
        [ True,  True,  True],
        [ True,  True,  True],
        [ True,  True,  True],
        [ True,  True,  True],
        [ True,  True,  True]],

       [[ True,  True,  True],
        [ True,  True,  True],
        [ True,  True,  True],
        [ True,  True,  True],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True,  True,  True],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True,  True,  True],
        [ True, False, False],
        [ True,  True,  True],
        [ True,  True,  True]],

       [[ True,  True,  True],
        [ True,  True,  True],
        [ True,  True,  True],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [False, False, False],
        [ True, False, False],
        [ True,  True,  True],
        [ True,  True,  True]],

       [[ True,  True,  True],
        [ True,  True,  True],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [False, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [False, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True,  True,  True],
        [ True,  True,  True]],

       [[ True,  True,  True],
        [ True,  True,  True],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [False, False, False],
        [False, False, False],
        [False, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True,  True,  True],
        [ True,  True,  True]],

       [[False, False, False],
        [False, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [False, False, False],
        [False, False, False]],

       [[False, False, False],
        [False, False, False],
        [False, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [False, False, False],
        [False, False, False],
        [False, False, False]],

       [[False, False, False],
        [False, False, False],
        [False, False, False],
        [False, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [ True, False, False],
        [False, False, False],
        [False, False, False],
        [False, False, False],
        [False, False, False]],

       [[False, False, False],
        [False, False, False],
        [False, False, False],
        [False, False, False],
        [False, False, False],
        [False, False, False],
        [False, False, False],
        [False, False, False],
        [False, False, False],
        [False, False, False],
        [False, False, False],
        [False, False, False],
        [False, False, False],
        [False, False, False],
        [False, False, False],
        [False, False, False]],

       [[False, False, False],
        [False, False, False],
        [False, False, False],
        [False, False, False],
        [False, False, False],
        [False, False, False],
        [False, False, False],
        [False, False, False],
        [False, False, False],
        [False, False, False],
        [False, False, False],
        [False, False, False],
        [False, False, False],
        [False, False, False],
        [False, False, False],
        [False, False, False]]])
duckGray = np.array([
[255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255],
[255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255],
[255,255,255,255,201,201,201,201,201,255,255,255,255,255,255,255],
[255,255,255,201,201,201,201,201,201,201,255,255,255,255,255,255],
[255,255,255,150,201, 0,201,201,201,201,255,255,255,255,255,255],
[255,150,150,150,201,201,201,201,201,201,255,255,255,255,255,255],
[255,255,150,150,150,201,201,201,201,255,255,255,255,255,255,255],
[255,255,255,255,201,201,201,201,255,201,201,201,255,201,255,255],
[255,255,255,201,201,201,201,201,201,201,201,201, 0,201,255,255],
[255,255,201,201,201,201,201, 0,201,201,201, 0,201,201,255,255],
[255,255,201,201,201,201,201,201, 0, 0, 0,201,201,201,255,255],
[ 50, 50,201,201,201,201,201,201,201,201,201,201,201,201, 50, 50],
[ 50, 50, 50,201,201,201,201,201,201,201,201,201,201, 50, 50, 50],
[ 50, 50, 50, 50,201,201,201,201,201,201,201,201, 50, 50, 50, 50],
[ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50],
[ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50],
], dtype=np.uint8)
# 상단 2행 검은색
duckGray[:2,:]=0 # broadcast
plt.imshow(duckGray, cmap='gray')
<matplotlib.image.AxesImage at 0x1c63b6295d0>

# 하단 2행 검은색
#duckGray[15:,:]=0
duckGray[-2:,:]=0
plt.imshow(duckGray, cmap='gray')
<matplotlib.image.AxesImage at 0x1c63b823610>

# 왼쪽 2열 검은색
duckGray[:,:2] = 0
plt.imshow(duckGray, cmap='gray')
<matplotlib.image.AxesImage at 0x1c63b8415d0>

실질적으로 테두리를 검게하는 코드

back=np.zeros((16,16))
back[2:14,2:14] = duckGray[2:14,2:14]
plt.imshow(back, cmap='gray')
<matplotlib.image.AxesImage at 0x1c63b8d95d0>

댓글남기기