前提・実現したいこと
白地に絵が描いてある画像を与えたときに、絵が描いてある部分だけを切り抜くプログラムを作っています。
白地に絵が描いてるものでどんなものを与えても絵を切り抜けるようにしたいです。
発生している問題・エラーメッセージ
今現在できているものである程度はできるのですがたまに変なところを切り抜く時があります。
該当のソースコード
clip
1import numpy as np 2import cv2 3 4 5#関数定義 6def cannyprocess(img, basename): 7 edges = cv2.Canny(img,100,200) 8 cv2.imwrite("canny\" + basename,edges)#エッジ画像保存 9 can_img = cv2.imread("canny\" + basename)#エッジ画像の読み込み 10 return can_img 11 12def contourprocess(img): 13 gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY) 14 image, contours, hierarchy = cv2.findContours(gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) 15 return contours 16 17def maskgenerate(img, basename): 18 back = np.zeros_like(img) 19 cont = contourprocess(cannyprocess(img,basename)) 20 mask = cv2.drawContours(back, cont, -1, color=(255, 255, 255), thickness=-1) 21 cv2.imwrite("mask\" + basename,mask) 22 mask = cv2.imread("mask\" + basename,0) 23 return mask 24 25def mask_and_alpha(base_img, mask_img, basename): 26 bgr_img = cv2.split(base_img) 27 clip = cv2.merge(bgr_img + [mask_img]) 28 cv2.imwrite("clip\" + basename,clip) 29 return clip 30 31#関数定義
main
1# -*- coding: utf-8 -*- 2 3from random import random 4from kivy.app import App 5from kivy.config import Config 6import clip 7import cv2 8import os 9 10# 起動時の解像度の設定 11Config.set('graphics', 'width', '1024') 12Config.set('graphics', 'height', '768') # 16:9 13Config.set('graphics', 'resizable', False) # ウインドウリサイズ禁止 14 15from kivy.uix.widget import Widget 16from kivy.uix.button import Button 17from kivy.graphics import Color, Ellipse, Line 18from kivy.properties import ObjectProperty 19from kivy.uix.behaviors import ToggleButtonBehavior 20from kivy.uix.togglebutton import ToggleButton 21from kivy.utils import get_color_from_hex # 色の16進数表示を可能にする 22from kivy.core.window import Window 23 24class MyPaintWidget(Widget): 25 #pass 26 last_color = '' # 画面クリアを押された場合の最後の色 27 line_width = 3 # 線の太さ 28 29 def on_touch_down(self, touch): 30 if Widget.on_touch_down(self, touch): 31 return 32 33 34 color = (random(), 1, 1) 35 with self.canvas: 36 touch.ud['line'] = Line(points=(touch.x, touch.y), width=self.line_width) 37 38 def set_line_width(self, line_width=3): 39 self.line_width = line_width 40 41 def on_touch_move(self, touch): 42 if touch.ud: # スライダーを動かす際のエラーを解除するため 43 touch.ud['line'].points += [touch.x, touch.y] 44 45 def set_color(self, new_color): 46 self.last_color = new_color 47 self.canvas.add(Color(*new_color)) 48 49class MyCanvasWidget(Widget): 50 51 def clear_canvas(self): 52 MyPaintWidget.clear_canvas(self) 53 54 55class MyPaintApp(App): 56 57 def __init__(self, **kwargs): 58 super(MyPaintApp, self).__init__(**kwargs) 59 self.title = '画像表示' 60 61 def build(self): 62 parent = Widget() 63 self.painter = MyCanvasWidget() 64 65 # 起動時の色の設定を行う 66 self.painter.ids['paint_area'].set_color(get_color_from_hex('#000000')) #黒色を設定 67 return self.painter 68 69 def clear_canvas(self): 70 self.painter.ids['paint_area'].canvas.clear() 71 self.painter.ids['paint_area'].set_color(self.painter.ids['paint_area'].last_color) 72 73 def save_canvas(self): 74 filename_base = 'sample.png' 75 img_path = Window.screenshot("base\" + filename_base) # スクリーンショットを保存する 76 basename = os.path.basename(img_path) 77 img = cv2.imread("base\" + basename) 78 cv2.rectangle(img, (0, 0), (78, 39), (255, 255, 255), thickness=-1) 79 img = img[0:637, 0:1024] 80 clip.mask_and_alpha(img, clip.maskgenerate(img, basename), basename) 81 82class ColorButton(ToggleButton): 83 84 def _do_press(self): 85 if self.state == 'normal': 86 ToggleButtonBehavior._do_press(self)# ボタンを押されてない場合は状態を変更する 87 88 89if __name__ == '__main__': 90 Window.clearcolor = get_color_from_hex('#ffffff') # ウィンドウの色を白色に変更する 91 MyPaintApp().run() 92
mypaint
1#:import hex_color kivy.utils.get_color_from_hex 2 3<ColorButton>: 4 background_normal: 'color_button_normal.png' 5 background_down: 'color_button_down.png' 6 group: 'color' 7 border: (5, 5, 5, 5) 8 on_release: app.painter.ids['paint_area'].set_color(self.background_color) 9 #on_release: app.painter.paint_id.set_color(self.background_color) # こ�?�方法でもset_corlorにアクセス可能 10<MyCanvasWidget>: 11 paint_id:paint_area 12 id: canvas_area 13 14 test:button1 15 Button: 16 text: 'save' 17 color: 1, 1, 1 , 1 18 font_size: 20 19 on_release: app.save_canvas() 20 border: (2, 2, 2, 2) 21 x: 0 22 top: root.top 23 width: 80 24 height: 40 25 26 BoxLayout: 27 orientation: 'vertical' 28 height: root.height 29 30 width: root.width 31 MyPaintWidget: 32 id: paint_area 33 size_hint_y: 0.8 34 35 BoxLayout: 36 orientation: 'horizontal' 37 size_hint_y: 0.1 38 Label: 39 size_hint_x: 0.1 40 text: 'Line width %s' % int(s1.value) if s1.value else 'Line width not set' 41 color: 0,0,0,1 42 Slider: 43 id: s1 44 size_hint_x: 0.9 45 value: 3 46 range: (1,100) 47 step: 1 48 on_touch_down:app.painter.ids['paint_area'].set_line_width(self.value) 49 50 BoxLayout: 51 orientation: 'horizontal' 52 size_hint_y: 0.1 53 clear_btn:button1 54 Button: 55 id: button1 56 text: "Clear" 57 ont_size: 30 58 on_release: app.clear_canvas() 59 60 61 ColorButton: 62 text: "white " 63 color: 0, 0, 0 , 1 64 background_color: hex_color('#ffffff') 65 66 ColorButton: 67 text: "black " 68 state: 'down' 69 background_color: hex_color('#000000') 70 71 ColorButton: 72 text: "red " 73 background_color: hex_color('#ff0000') 74 75 ColorButton: 76 text: "biue " 77 background_color: hex_color('#0000ff') 78 79 ColorButton: 80 text: "green " 81 background_color: hex_color('#008000') 82 83 ColorButton: 84 text: "orange" 85 background_color: hex_color('#ff4500') 86 87 ColorButton: 88 text: "purple" 89 background_color: hex_color('#800080')
clip,mainにはそれぞれ拡張子として.py、mypaintには.kvが付きます
↑失敗例の切り抜き画像
補足情報(FW/ツールのバージョンなど)
python 3.6.8
opencv 3.4.2
第三者が動作検証できるようにmain処理部分も含めたソースと変になる画像(と変になる例)を添えると回答得られやすいと思います。
回答2件
あなたの回答
tips
プレビュー