반응형

     정보

    • 업무명     : 아이디엘 이미지 처리 (Image Processing) 교육 연수

    • 작성자     : 이상호

    • 작성일     : 2020-04-03

    • 설   명      :

    • 수정이력 :

     

     내용

    [개요]

    • 안녕하세요? 기상 연구 및 웹 개발을 담당하고 있는 해솔입니다.

    • 오늘은 에스이랩 이미지 처리 (Image Processing) 교육 연수 내용을 다루고자 합니다.

    • 이 교육은 2일에 걸쳐 진행하였고 각 시간마다 이론 및 실습을 병행하여 진행했습니다.

    • 특히 배운 지식을 활용하여 학술 논문 또는 보고서 작성 시 많은 도움이 되었습니다.

    • 그에 따라 "교육 일정, 실습 자료, 관련 자료"순으로 소개해 드리겠습니다.

     

     

    [특징]

    • 이미지 처리 (Image Processing) 교육에 대한 이해를 돕기위해 작성

     

    [기능]

    • 교육 일정

     

    [사용 OS]

    • Window 10

     

    [사용 언어]

    • IDL v8.5

     

     세부 내용

    [교육 일정]

    • 1일

      • 10:00-10:50 이미지 소개

      • 11:00-11:50 이미지 파일 다루기

      • 13:00-13:50 이미지의 표출

      • 14:00-14:50 기본적인 이미지 처리법 1

      • 15:00-15:50 기본적인 이미지 처리법 2

      • 16:00-17:00 컬러를 다루는 법

     

    • 2일

      • 10:00-10:50 이미지의 저장

      • 11:00-11:50 실전 이미지 처리 기법 1

      • 13:00-13:50 실전 이미지 처리 기법 2

      • 14:00-14:50 관심영역(ROI)의 활용

      • 15:00-15:50 형태의 추출 및 분석

      • 16:00-17:00 기타 이슈들

     

     실습 자료

    • 소스 코드에 대한 설명은 주석을 참조하시기 바랍니다.

     

    pro test_01
    
        file = 'data/AHI_b03.png'
    
        help, file
    
        ;  read_png, file, img
        read_png, file, png_img
        ;help, png_img
        ;print, size(png_img, /dim)
    
        result = size(png_img, /dim)
        ;help, result
        ;print, result[0], result[1]
    
        window, 0, xsize=result[0]/2, ysize=result[1]/2 ; window, xsize=1024, ysize=768
        tv, png_img
    
        window, 1, xsize=result[0]/2, ysize=result[1]/3
        tvscl, png_img
    
        ;********************** 재활용 *************************8
        ;window, 1, xsize=result[0], ysize=result[1]
        ;tv, img_png > 90 < 200
    
        ;window, 2, xsize=result[0], ysize=result[1]
        ;tvscl, img_png > 90 < 200
    
    end

     

    pro test_02
    
        img1 = hanning(300, 300)*60 
        img2 = hanning(300, 300)*120
        img3 = hanning(300, 300)*200
        ; 2차원을 가상으로 만듬. ; hanning은 신호처리 함수 중의 하나 ; 0과 1의 데이터로 만들어짐. 
        ; 
        ; print, min(img), max(img) 
    
        device, decomposed=0  
        ; 8비트 기반으로 색깔을 해석해라.
        ; IDL을 처음 띄운상태는 컴퓨터 체계 그래도 쓰임. 24인 비트인 RGB로 해석하므로 내가 255인 값을 색깔로 해석할려면 / 단일 값에 해당하는
        ; 값으로 해석함. 
    
        ; window
        ; erase, 255 이므로 R G B을 255 0 0 으로 컴퓨터가 알아서 해석함. / 컴퓨터가 자체가 8비트로 안되어 있으므로  일단, 빨강색으로 나옴.
        ; device, decomposed=0 으로 하면 8비트로 해석하므로 
        ; erase, 255로 하면 흰색이 나옴. 단일값이므로
    
        window, xsize = 300*3, ysize = 300
    
        loadct, 13 
        ; ct는 컬러테이블로써 5번의 약속으로 맵핑을 해라. 0~74까지의 값으로 나옴. 컬러테이블이 어떤 색인지 짐작할 수 없음.
        ;  미리 확인할려면 콘솔창에 xloadct로 치면 창이 나옴.  13으로 하면 레인보우로 나옴. 75개로 선택은 다양해짐. 
        ; xloadct
        ; done 버튼을 누르면서 다음에 나올 번호를 이용해서 사용할 수 있음.
        ; 
        ; xpalette
        ; 특정 색깔에 대해서 나옴. RGB도 확인할 수 있음. 256의 색상은 고유 RGB색깔을 가지고 있음. 그러므로 컬러테이블을 내가 만들 수도
        ; 있음. 컬러테이블은 조금 있다가 함.
    
        ;  tvscl, img1, 0 
        ;  tvscl, img2, 1
        ;  tvscl, img3, 2
        ; 순서가 순차적으로 매겨짐. 0~255의 스케일로 보여줌으로써 다 똑같이 보이므로 가시적으로 볼려면 tv로 봐야함
    
        tv, img1, 0
        tv, img2, 1
        tv, img3, 2
    
        loadct, 0
        ; 뒤의 프로그램의 프로그램의 잔재를 남게 하지 않게할려고
    
    end

     

    pro test_03
    
        ; 아직도 컬러테이블이 흑백이였으나, 앞의 프로그램의 컬러테이블의 잔재가 남은 경우가 있음. 그래서 test_02.pro에 마지막에
        ; loadct, 0으로 컬러테이블 끝남
    
        ; 1024,764 데이터
        file = 'data/bw0406.jpg'
        read_jpeg, file, img
        result = size(img, /dim)
        window, 0,  xsize=result[0], ysize=result[1] 
        tv, img
    
        print, img[512,384]
        ; 화소값을 뽑아낼려면 x방향으로 513번쨰, y방향으로 385번쨰 화소의 값에 대해서 뽑아냄
    
        print, img[50,50]
    
        ; print, img[*, 384]
        ; 가로방향으로 수평 스캔으로하면 하나의 스트림을 뽑아낼려고 함. 특정 차원에 대해서 모두 뽑아낼려면 * 방향, 보기 너무 어려우므로
    
        window, 1
        for i = 0, 400 do begin
        ; 반복문할떄 0으로 안해도 되지만, 배열 자체가 0으로 하므로 / 반복문 구조 (for ~ endfor)
    
        line = img[*, i]
        ;   help, line
    
        plot, line, yrange=[0, 255], YST=1
        ; ystyle(YST)=1 
    
    
        wait, 0.1
        ; plot을 점점 바꿔짐. 즉, y축이 자꾸 변하여 비교하기 어려움. 0.1초씩 다른거를 해라
    
    
        ; 별도의 창을 만들지 않을 경우에 그래픽창이 계속 누적됨. 그래서 window, 1로서 설정해주어야 함. 제목 창에 window 0~1으로 보여줌.
        ; 그래서 인덱스 별로 따로 구분할 경우도 있음.  
        ; y축을 고정하지 않을경우, y축이 이동되므로 비교하기 어려움.
    
        ; IDL도 반복문, 조건문이 주어짐. 반복적으로 작업을 할떄 사용함.
    
        endfor
        ; 주석을 여러개 달떄 ctrl + ; 으로 시작 함.
    
    end

     

    pro test_04
    
        ; 아직도 컬러테이블이 흑백이였으나, 앞의 프로그램의 컬러테이블의 잔재가 남은 경우가 있음. 그래서 test_02.pro에 마지막에
        ; loadct, 0으로 컬러테이블 끝남
    
        ; 1024,764 데이터
    
        file = 'data/bw0406.jpg'
        read_jpeg, file, img
        result = size(img, /dim)
        window, 0,  xsize=result[0], ysize=result[1]
        tv, img
    
        print, img[512,384]
        ; 화소값을 뽑아낼려면 x방향으로 513번쨰, y방향으로 385번쨰 화소의 값에 대해서 뽑아냄
    
        print, img[50,50]
    
        img_sub = img[300:499, 100:299]
        ; 일부 영역을 뽑아낼려면 x축 300개, y축 300개에 대한 영역을 뽑아냄.
    
        help, img_sub
    
        window, 1, xsize=300, ysize=300
        tv, img_sub
    
        ;  window, 2, xsize=300*3, ysize=300*3
    
        ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
        mf=3
        window, 2, xsize=200*mf, ysize=200*mf
        ; 뽑아낸 좌표를 확대함. 가로/세로 확대함.
    
        img_sub_zoom = congrid(img_sub, 200*mf, 200*mf)  
        tv, img_sub_zoom
        ; 확대 명령어 congrid임. 원본데이터는 300,300인데 900,900으로 없는 값을 채워야하는 알고리즘이 있음. 
    
        window, 3, xsize=200*mf, ysize=200*mf
        img_sub_zoom = congrid(img_sub, 200*mf, 200*mf, /interp)
        tv, img_sub_zoom
        ; window, 2보다 조금 더 부드러움. 꺠끗하게 보임. / interpolation을 새롭게 새로운 값을 내삽하여 부드럽게 보임. 밝기에 대한 부드러움의 차이.
        ; 
        ; rebin은 정수에 대해서만 한계를 가짐. 
        ; congrid는 defalult로 neaest sampling으로 되어있으나, 옵션으로 interp 있음.
        ; 
        ; Nearest은 가까이 있는 실제값을 넣는 방법이므로 마치 크게 깍두기 생긴 것과 같다. 계단적으로 굉장히 거칠게 보임. 화소 차이가 큼.
        ; 픽셀만 커진 내용임, 절대 원본값으로 살리고 싶으면 이 방법이 좋으나
    
        ; interplolation은 원본값은 살리지 않고 원본에 존재하지 않은 값을 중간에 이어 붙임. 눈으로 보이게 부드러워 보임. interplolation은 Bilinear해도
        ; 충분함. 많은 내삽의 방법도 있음.  
    
        ;  a = [1., 2., 3.]
        ;  print, congrid(a, 6)
        ;  print, congrid(a, 6, /interp)
        ;  둘의 차이가 있음.
    
        ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
        line = img[*,383]
    
        ; pl = plot(line, yrange=[0,255], color='blue' ) 
        ; function, 프로시저로 구분함.
        ; NG 방식으로 test_03.pro와 큰 차이가 없다. 계속적으로 설명 해줌. 곧곧에 편리한 기능을 가짐. 이미지에 대해서 한 포인트, 한 라인에 대해서
        ; 추출했다. / 이제는 그 데이터의 일부만 뽑아낼려면
      
    end

     

    pro test_05
    
        file = 'data/20140709_000000_Ic_flat_1k.jpg'
        ; 파일 속성에 24비트로 되어 있으므로 RGB로 되어있음.
    
        read_jpeg, file, img
        ; 원본이 RGB일 경우
    
        read_jpeg, file, img, /gray
        ; 원본 RGB ==> 그레이 색으로 바꿈으로써 더 편함. 마우스를 띄움으로써 기본적인 정보를 보여줌.  IDL을 생략해도 쓸 수 있음.
    
        help, img
    
        window,  0, xsize=1024, ysize=1024
        tv, img
        ;tv, img, /true
        ; 원본이 RGB일 경우, true 컬러 이미지에 대해서 보여줌.
    
        img_sub = img[500:899, 300:699]
        sz = size(img_sub, /dim)
        window, 1, xsize=sz[0], ysize = sz[1]
        tv, img_sub
        ; 어두운 흑점에 대해서 관심이 있을경우, 히스토그램으로 img_sub의 빈도분포를 보자
    
        ;pl = plot(histogram(img_sub))
        pl = plot(histogram(img_sub), yrange=[0,100])
        ; 180값보다 낮은 값이 관심이 있음. 화소값 중심으로 히스토그램으로 그려봐서 알 수 있음. 180을 기준으로 낮은 값만 뽑아내면 그것이 
        ; 바로 흑점이라고 생각하여함.
    
        window, 2, xsize = sz[0], ysize = sz[1]
        img_sub_mask = img_sub ge 130 and img_sub lt 180
        ; 180보다 낮으므로 0,1로 환산되어 나타남. 180보다 작으면 true(1), 180보다 크거나 같으면 false(0). 모든 화소에 대해서 생각해줌.
        print, min(img_sub_mask), max(img_sub_mask)
        ; 0, 1밖에 없으므로 바이너리 이미지로 보임
    
        ;tv, img_sub_mask
        ; 0과 1로서 색깔이 보임.
        ;tvscl, img_sub_mask
        ; 흑점에 대해서만 보여줌. 0과 1로 극명하게 보여줌으로 / 이것이 마스킹이라고 함. 문법이 허무하게 끝날정도로 간단함. 화소값을 기준으로
        ; 값을 쉽게 뽑아 낼수 있음.
        tvscl, img_sub_mask*img_sub
        ; 히스토그램으로 값에 대해서 극명하게 보여줌.  원본이미지 색깔과 똑같이 만들어주고, 그에 따라 아닌값은 0으로 판단해줌.즉, 그 부분만
        ; 마스킹 되는 기법임. 내가 생각한 흑점에 대해서만 보여줌. 
    
        ;*********************************************** 클리핑 *******************************************
        ; 150보다 크면 150으로 맞추고, 90보다 낮으면 90으로 맞추니깐 90~150 사이 값에 대해서만 보여줌. 나머지 값인 값들은 사라짐. 
        ; 90보다 작고, 150보다 작은 값은 없어짐.  tvscl은 0~255으로 재 조정됨.
    
        window, 3, xsize = sz[0], ysize = sz[1]
        tvscl, img_sub > 130 < 180
        ; 130보다 어두운 부분 없어지고, 180보다 높은 부분 없어짐.
    
    end

     

    pro test_06
    
        file = 'data/rduck2.jpg'
        read_jpeg, file, img, /gray
        help, img
    
        img_new = congrid(img, 3264/4, 2448/4, /interp)
        sz = size(img_new, /dim)
    
        window, 0, xs=sz[0], ys=sz[1]
        tv, img_new
    
        window, 1, xs=sz[0], ys=sz[1]
    
        loadct, 0
        ;loadct, 14
        ; 컬러테이블로 이용해서 나타낼 수도 있음.S
    
        tvscl, img_new < 50 
        ; 원본에서 어둡게 나타났던것이 밝기 디테일이 강조되어서 나타났다. 나무의 그림자가 더 뚜렷하게 보임. 잔디밭과 약간의 음명이 보임. 
        ; 내가 얻고자 하는 정보를 구함. 근데, 밝기 높은 부분을 포기하고 어두운 부분을 보기 위한 클리핑임.
        ; 어느정도 정량적으로 클리핑값을 구할려면 히스토그램으로 수치적으로 판단함.
    
        pl = plot(histogram(img_new))
    
        ; 클리핑과 마스킹을 통해서 내가 볼 수 있는 이미지를 새롭게 볼 수 있음. 내가 원하던 정보를 볼 수 있음. 쓰는 방법이 난이도는 베이직하나? 
        ; 베이직한 결과지만 유용한 역할을 할 수 있음. 
        ; 다음 시간은 컬러테이블을 만드는 역할.
    
    end

     

    pro test_07
    
        img = hanning(600, 600)
        win = window( dimension = [600, 600] )
        ; NG체계의 함수형으로 되어있으므로 ( )로 되어있음. NG = function 기반 그래픽. 400, 400에 대한 창을 띄워라!
        ; 그래픽 창에 꽉 채우지 않으므로 
    
        im = image( img, rgb_table=14, margin=0, /current )
        ; 이미지 선택 후 이미지 자체의 x, y, 화소값을 볼 수 있음. 간단한 문자삽입하거나 저장 할 수 있음.
        ; 여기에서 컬러테이블 저장할떄, rgb_table=5로서 색깔됨.
        ; 그래픽을 꽉채우게 할려면 margin=0을 하면 꽉차게 그려짐.
    
        tx = text(0.5, 0.93, 'Test Image', alignment=0.5, /normal, $
          color = 'yellow', font_size=20)
        ; 문자를 삽입.  0~1, 0~1로 계산하는 /normal로 생각함.  alignment=왼쪽/오른쪽 삽입. 이어서 하는줄은 $.
        ; 문자 폰트 떄문에 NG을 주로 이용함. 대외적인 결과물을 이용함. 
    
        ;win.save, 'test_07.png'
        ; 저장하는데 test_07.png로서 알아서 픽셀값에 저장되므로 명시적으로 x,y을 설정하는게 좋음.
    
        win.save, 'test_07.png', width=600
        win.save, 'test_07.jpg', width=600
        win.save, 'test.pdf'
        ; 확장자에 따라 알아서 그림을 저장할 수 있음. save Method가 저장할떄 쓰는 종속된 변위임.
    
    end

     

     

    pro test_08
    
        img = hanning(600, 600) * 10
        img[400,500] = -9999.
    
        window, 0, xsize=600, ysize=600
        tvscl, img 
        ; 0~10까지 범위를 알아서 설정함.
    
        window, 1, xsize=600, ysize=600
        tv, bytscl(img)
    
        window, 2, xsize=600, ysize=600
        img_new = bytscl(img, max=10, min=0)
        tv, img_new
        ; 최대, 최소에 대한 범위를 정해줄 수 있음. -9999가 있다고 하더라도 상관없음. 
        ; 만약에 특정 픽셀이 이상한 값이 있다고 한다면 -9999.을 0으로 되어있지만, 10으로 되는 값은 255 근처의 값으로 하면 모두 하얗게 보임.
        ; bytscl로 한번 값을 거친 후 해결하는 게 좋음.
    
    end

     

    pro cloud_mask_01
    
        file = 'data/AHI_b03.png'
    
        help, file
        read_png, file, img
        help, img
        ;print, size(png_img, /dim)
    
        result = size(img, /dim)
        ;help, result
        ;print, result[0], result[1]
    
        ;  window, 0, xsize=result[0], ysize=result[1] 
        ;  tv, img
        ;
        ;  ;pl = plot(histogram(img))
        ;
        ;  window, 1, xsize=result[0], ysize=result[1] 
        ;  img_mask = ( img ge 40 and img lt 250 )
        ;  print, min(img_mask), max(img_mask)
        ;  
        ;  tvscl, img_mask*img
        ;  
        ;  window, 2, xsize=result[0], ysize=result[1]
        ;  tvscl, img > 150 < 250
    
        img = img > 80
        win = window(dimension=[800, 800])
        im = image(img, rgb_table=0, margin=0, /current)
        tx = text(0.5, 0.95, 'AHI b03', alignment=0.5, /normal, color='blue', font_size=20, $
        font_name='Times', font_style='bold')
        ;win.save, 'OUTPUT/cloud_mask01.pdf'
    
    
        stop
    
    end
    

     

     

     관련 자료

    • 강의안 및 교육 자료 참조

     

    01. [에스이랩] IDL Image processing.7z

     

    drive.google.com

     

     참고 문헌

    [논문]

    • 없음

    [보고서]

    • 없음

    [URL]

    • 없음

     

     문의사항

    [기상학/프로그래밍 언어]

    • sangho.lee.1990@gmail.com

    [해양학/천문학/빅데이터]

    • saimang0804@gmail.com
    반응형
    • 네이버 블러그 공유하기
    • 네이버 밴드에 공유하기
    • 페이스북 공유하기
    • 카카오스토리 공유하기