前提・実現したいこと
白地に描いた絵の一番外側の線(絵と白地の境界部分)で絵を切り抜き、その周りに透過処理を施した画像を作成したいです。
発生している問題・エラーメッセージ
切り抜くこと自体はできるのですが、マスク画像が意図しない形で生成されてしまい、変な風に切り抜いてしまいます。
↑元画像
↑マスク画像
↑切り抜き後の画像
ソースコード
main.py
# -*- coding: utf-8 -*- from random import random from kivy.app import App from kivy.config import Config import clip import cv2 import os # 起動時の解像度の設定 Config.set('graphics', 'width', '1024') Config.set('graphics', 'height', '768') # 16:9 Config.set('graphics', 'resizable', False) # ウインドウリサイズ禁止 from kivy.uix.widget import Widget from kivy.uix.button import Button from kivy.graphics import Color, Ellipse, Line from kivy.properties import ObjectProperty from kivy.uix.behaviors import ToggleButtonBehavior from kivy.uix.togglebutton import ToggleButton from kivy.utils import get_color_from_hex # 色の16進数表示を可能にする from kivy.core.window import Window class MyPaintWidget(Widget): #pass last_color = '' # 画面クリアを押された場合の最後の色 line_width = 3 # 線の太さ def on_touch_down(self, touch): if Widget.on_touch_down(self, touch): return color = (random(), 1, 1) with self.canvas: touch.ud['line'] = Line(points=(touch.x, touch.y), width=self.line_width) def set_line_width(self, line_width=3): self.line_width = line_width def on_touch_move(self, touch): if touch.ud: # スライダーを動かす際のエラーを解除するため touch.ud['line'].points += [touch.x, touch.y] def set_color(self, new_color): self.last_color = new_color self.canvas.add(Color(*new_color)) class MyCanvasWidget(Widget): def clear_canvas(self): MyPaintWidget.clear_canvas(self) class MyPaintApp(App): def __init__(self, **kwargs): super(MyPaintApp, self).__init__(**kwargs) self.title = '画像表示' def build(self): parent = Widget() self.painter = MyCanvasWidget() # 起動時の色の設定を行う self.painter.ids['paint_area'].set_color(get_color_from_hex('#000000')) #黒色を設定 return self.painter def clear_canvas(self): self.painter.ids['paint_area'].canvas.clear() self.painter.ids['paint_area'].set_color(self.painter.ids['paint_area'].last_color) def save_canvas(self): filename_base = 'sample.png' img_path = Window.screenshot("base\" + filename_base) # スクリーンショットを保存する basename = os.path.basename(img_path) img = cv2.imread("base\" + basename) cv2.rectangle(img, (0, 0), (78, 39), (255, 255, 255), thickness=-1) img = img[0:637, 0:1024] clip.mask_and_alpha(img, clip.maskgenerate(img, basename), basename) class ColorButton(ToggleButton): def _do_press(self): if self.state == 'normal': ToggleButtonBehavior._do_press(self)# ボタンを押されてない場合は状態を変更する if __name__ == '__main__': Window.clearcolor = get_color_from_hex('#ffffff') # ウィンドウの色を白色に変更する MyPaintApp().run()
clip.py
import numpy as np import cv2 #関数定義 def cannyprocess(img, basename): edges = cv2.Canny(img,100,101,None, 3, True) cv2.imwrite("canny\" + basename,edges)#エッジ画像保存 can_img = cv2.imread("canny\" + basename)#エッジ画像の読み込み return can_img def contourprocess(img): gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY) image, contours, hierarchy = cv2.findContours(gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) print(hierarchy) return contours def maskgenerate(img, basename): back = np.zeros_like(img) cont = contourprocess(cannyprocess(img,basename)) mask = cv2.drawContours(back, cont, -1, color=(255, 255, 255), thickness=-1) cv2.imwrite("mask\" + basename,mask) mask = cv2.imread("mask\" + basename,0) return mask def mask_and_alpha(base_img, mask_img, basename): bgr_img = cv2.split(base_img) clip = cv2.merge(bgr_img + [mask_img]) cv2.imwrite("clip\" + basename,clip) return clip #関数定義
mypaint.kv
#:import hex_color kivy.utils.get_color_from_hex <ColorButton>: background_normal: 'color_button_normal.png' background_down: 'color_button_down.png' group: 'color' border: (5, 5, 5, 5) on_release: app.painter.ids['paint_area'].set_color(self.background_color) #on_release: app.painter.paint_id.set_color(self.background_color) # こ�?�方法でもset_corlorにアクセス可能 <MyCanvasWidget>: paint_id:paint_area id: canvas_area test:button1 Button: text: 'save' color: 1, 1, 1 , 1 font_size: 20 on_release: app.save_canvas() border: (2, 2, 2, 2) x: 0 top: root.top width: 80 height: 40 BoxLayout: orientation: 'vertical' height: root.height width: root.width MyPaintWidget: id: paint_area size_hint_y: 0.8 BoxLayout: orientation: 'horizontal' size_hint_y: 0.1 Label: size_hint_x: 0.1 text: 'Line width %s' % int(s1.value) if s1.value else 'Line width not set' color: 0,0,0,1 Slider: id: s1 size_hint_x: 0.9 value: 3 range: (1,100) step: 1 on_touch_down:app.painter.ids['paint_area'].set_line_width(self.value) BoxLayout: orientation: 'horizontal' size_hint_y: 0.1 clear_btn:button1 Button: id: button1 text: "Clear" ont_size: 30 on_release: app.clear_canvas() ColorButton: text: "white " color: 0, 0, 0 , 1 background_color: hex_color('#ffffff') ColorButton: text: "black " state: 'down' background_color: hex_color('#000000') ColorButton: text: "red " background_color: hex_color('#ff0000') ColorButton: text: "biue " background_color: hex_color('#0000ff') ColorButton: text: "green " background_color: hex_color('#008000') ColorButton: text: "orange" background_color: hex_color('#ff4500') ColorButton: text: "purple" background_color: hex_color('#800080')
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2019/08/07 04:40