ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 사진을 스케치 이미지로 변경하기, picture to sketch image
    이미지 처리 2021. 5. 13. 11:23

    사진을 스케치 이미지로 변경하는 경우

    보통 opencv2 에서 제공하는 기능을 이용해서 스케치를 많이 생성합니다.

     

     

    하지만, 정도의 차이는 있겠지만

    아래 이미지를 보는 것처럼 사람이 그린것 같지 않고,

    희미하거나 불필요한 선들이 많이 있는 것을 볼 수가 있습니다.

     

     

    선을 좀 더 사람이 그린 것처럼 만들기 위해 찾아본 결과,

    sketch_simplification 에서 제공해주는 머신러닝을 이용하게 되면 좀 더 좋은 결과로 나오는 것을 확인하였습니다.

    출처: github.com/bobbens/sketch_simplification

     

     

    그래서 sketch_simplification 을 사진에서 바로 적용을 하게 되면,

    다음처럼 까맣게만 나오는 것으로 확인하였습니다.

    sketch_simplification 사용하는 방법은 위에 언급한 출처의 readme 를 참조 바랍니다.

     

    원본:

    결과:

     

    따라서, 언급했던 것처럼 

    까맣게만 나오므로 바로 사용할 수가 없습니다.

     

    이에 대한 대응 방법으로 opencv2 를 이용해서

    cvtColor() 으로 gray 색으로 변경, 

    GaussianBlur() 으로 블러처리한 후,

    divide() 으로 gray_image 에서 255 - (GaussianBlur 처리한 변수)를  나누기 연산해서 결과를 만듭니다.

     

     

    중간 GaussianBlur, divide 까지 처리 후 나온 결과 이미지:

    최종 결과:

     

    자세한 코드는 다음과 같습니다.

    parser = argparse.ArgumentParser(description='Sketch simplification demo.')
    
    parser.add_argument('--model', type=str, default='model_gan.t7', help='Model to use.')
    parser.add_argument('--img',   type=str, default='original.jpg',     help='Input image file.')
    parser.add_argument('--out',   type=str, default='결과 파일',      help='File to output.')
    opt = parser.parse_args()
    
    
    def make_pencil_image():
       """
          sketch_simplification
          use https://github.com/bobbens/sketch_simplification/blob/master/simplify.py
       """
    
       use_cuda = torch.cuda.device_count() > 0
    
       cache = load_lua(opt.model, long_size=8)
       # cache  = torchfile.load( opt.model )
       model  = cache.model
       immean = cache.mean
       imstd  = cache.std
       model.evaluate()
    
       data = Image.open( opt.img ).convert('L')
    
       w, h = data.size[0], data.size[1]
       pw = 8-(w%8) if w%8!=0 else 0
       ph = 8-(h%8) if h%8!=0 else 0
    
       print('start unsqueeze()')
    
       data = ((transforms.ToTensor()(data)-immean)/imstd).unsqueeze(0)
       if pw != 0 or ph != 0:
          data = torch.nn.ReplicationPad2d( (0,pw,0,ph) )( data ).data
    
       print('start ReplicationPad2d()')
       if use_cuda:
          print(' use cuda')
          pred = model.cuda().forward( data.cuda() ).float()
       else:
          print('don\'t use cuda')
          pred = model.forward( data )
       save_image(pred[0], opt.out)
    
    
    def make_simplify_image():
    
       gray_image = make_gray_image()
       make_pencil_image()
    
    
    def make_gray_image():
       img = cv2.imread('처음 시작 이미지.png', cv2.IMREAD_UNCHANGED)
       # 이미지 흑백으로 변경
       gray_image = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    
       # not연산(반대로 하기)
       img_invert = cv2.bitwise_not(gray_image)
    
       # 가우시안 블러 적용
       # src: 적용 대상,
       # ksize: 가우시안 커널 크기. (0, 0)을 지정하면 sigma 값에 의해 자동 결정됨 - 
       # 숫자가 작으면 선이 유실되고,
       # 숫자가 많으면 선이 너무 찐하게 나와서 적정값이 21
       img_smoothing = cv2.GaussianBlur(img_invert, (21, 21), sigmaX=0, sigmaY=0)
       # gray_image 에서 255 - img_smoothing를 나누기 연산
       final_img = cv2.divide(gray_image, 255 - img_smoothing, scale=256)
    
       # 중간 이미지 생성
       cv2.imwrite('original.jpg', final_img)
       return final_img
    
    if __name__ == '__main__':
        make_simplify_image()
Designed by Tistory.