banner
肥皂的小屋

肥皂的小屋

github
steam
bilibili
douban
tg_channel

Python--証明写真の背景色を変更するための小さなプログラム

起因#

この記事AIの切り抜きライブラリremovebgが紹介されているのを見ました。

GitHub に行く公式サイトでオンラインで画像の背景を変更することができます。

切り抜きは、友人のためにやったこともありますが、実は自分もdoyoudoチュートリアルを見てやったことがあります。サイトで直接見るには登録が必要です。

登録したくない方は優酷で見ることができます。ここでdoyoudoというサイトをお勧めします(見たらお金をください、ありがとうございます):

doyoudo は、シンプルな音声・動画編集ソフトのチュートリアルサイトです。

チュートリアルに従って慣れたら、約 10 分で画像を編集できます。しかし!今はこの人工知能の切り抜きライブラリremovebgがあるので、効果を試してみる必要があります。

このライブラリの概要は以下の通りです:

デフォルトで生成される画像のフォーマットサイズは標準で、毎月最大 50 枚の写真を無料で処理できます。HD や 4K を生成したり、より多くの画像を処理したりするには有料です。計算すると、1 枚あたり約 1 元です。

そこで、このコアコードを使って、PyQt5の小プログラムを作成し、PyQt5のスキルを強化し、新しいことを学べるか見てみることにしました。

無 GUI バージョン#

** 注意:生成された画像は元の画像のディレクトリに保存され、ファイル名は画像名.画像拡張子から画像名.画像拡張子_no_bg.pngに変更されます。**

背景を置き換える#

登録してログインした後、サイトの API インターフェースから自分の API を取得し、以下の数行のコードで基本的な画像の背景置き換えを実現できます:

from removebg import RemoveBg
rmbg = RemoveBg("あなたのapikey", "error.log")
rmbg.remove_background_from_img_file(r"C:\Users\soapffz\Desktop\640_2.jpg") # 画像の位置

効果は以下の通りです:

image

image

image

画像の読み込み速度のため、ここでは画質が大幅に圧縮されていますので、気にしないでください。

** 本文で使用されているこのコアライブラリは、背景画像の背景を削除する機能のみを持っています ** 、他の色で塗りつぶすにはPILImageを使用します:

塗りつぶし色#

from PIL import Image
img = Image.open(r'640.png').convert("RGBA")
x, y = img.size
card = Image.new("RGBA", img.size, (0, 0, 255))
card.paste(img, (0, 0, x, y), img)
card.save("640_2.jpg", format="png")

効果は以下の通りです:

image

GUI バージョン#

** ここで、ずっと使っているが言い忘れていたPyQt5の部分的なテクニックを補足します **

GUI の設計#

基本的な設計チュートリアルは <<ローカル IP プロキシプールの構築 (完結)>> という記事にあります。この記事はPython ディレクトリで見つけることができます。

GUI デザイン図は以下の通りです:

image

ファイル選択#

参考記事:PyQt5 ファイルダイアログ QFileDialog の使用

単一ファイルを選択:

from os import path
from sys import argv

    self.exe_path = path.dirname(argv[0])  # 現在のプログラムの実行パスを取得
    self.pushButton.clicked.connect(self.chosepic) # ファイル選択ボタンが押されたときに関数をトリガー

    def chosepic(self):
        # 画像を選択
        file_name = QtWidgets.QFileDialog.getOpenFileName(
            self, "ファイルを選択", self.exe_path, "Pic Files (*.png;*.jpg);;Text Files (*.txt)")[0]   # ファイル拡張子フィルタを設定、二重セミコロンで区切る
        if file_name == "":
            print("ユーザーが選択をキャンセルしました")
            return
        print("選択したファイル:", file_name)

単一フォルダを選択:

from os import path
from sys import argv

    self.exe_path = path.dirname(argv[0])  # 現在のプログラムの実行パスを取得
    self.pushButton.clicked.connect(self.chosedir) # フォルダ選択ボタンが押されたときに関数をトリガー
    def chosedir(self):
        # 画像を含むフォルダを選択
        dir_name = QtWidgets.QFileDialog.getExistingDirectory(
            self, "フォルダを選択",  self.exe_path)
        if dir_name == "":
            print("\n選択をキャンセルしました")
            return
        print("選択したフォルダ:", dir_name)

ここでは一般的な二つの方法を紹介しました。複数ファイルの選択は、単一フォルダを選択してからファイル拡張子を判断する方法で実現できます。他の方法については参考記事を参照してください。

ポップアップ表示の実装#

よく使う関数:#

# 情報ボックス
QMessageBox.information(self, 'ボックス名', '内容', ボタンs, デフォルトボタン)
# 質問ボックス
QMessageBox.question(self, 'ボックス名', '内容', ボタンs, デフォルトボタン)
# 警告ボックス
QMessageBox.warning(self, 'ボックス名', '内容', ボタンs, デフォルトボタン)
# 危険ボックス
QMessageBox.critical(self, 'ボックス名', '内容', ボタンs, デフォルトボタン)
# 情報ボックス
QMessageBox.about(self, 'ボックス名', '内容')

例:

from PyQt5.QtWidgets import QMessageBox

# 退出確認ボックス
reply = QMessageBox.question(self, '退出', '本当に退出しますか?', QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel, QMessageBox.Cancel)
if reply == QMessageBox.Yes:
	print('退出')
else:
	print('退出しない')

image

カスタムメッセージボックス#

# 質問ボックスを作成、注意:Question
self.box = QMessageBox(QMessageBox.Question, '退出', '本当に退出しますか?')

# ボタンを追加、中文を使用可能
yes = self.box.addButton('はい', QMessageBox.YesRole)
no = self.box.addButton('キャンセル', QMessageBox.NoRole)

# メッセージボックスの内容の前にアイコンを設定
self.box.setIcon(1)

# メッセージボックスの位置を設定、サイズは設定できません
self.box.setGeometry(500, 500, 0, 0)

# この質問ボックスを表示
self.box.show()

if self.box.clickedButton() == yes:
	print('退出')
else:
	print('退出しない')

image

参考記事:

ハイパーリンクの設定#

一般的にはlabelコンポーネントに設定します。デザイン時に通常のテキストを入力し、その後以下の設定を行います:

self.label_getapi.setText("<a href='https://www.remove.bg/api'>APIKEYを取得するにはここをクリック:</a>") # ハイパーリンクテキストを設定
self.label_getapi.setOpenExternalLinks(True) # デフォルトブラウザでハイパーリンクを開くことを許可

チェックボックスで同じ関数を呼び出して状態を確認#

私のプログラム設計では、デフォルトで背景のない色の画像を生成する必要があり、その後に他の背景色を選択できます。

では、どの色に変換するかを取得するにはどうすればよいでしょうか?以下の方法で実現できます:

        self.bg_color_chose_l = []  # 変換する色のリスト
        self.checkBox_white.stateChanged.connect(self.checkstate)
        self.checkBox_blue.stateChanged.connect(self.checkstate)
        self.checkBox_red.stateChanged.connect(self.checkstate)
        self.pushButton_begin.clicked.connect(self.begin)
    def checkstate(self, state):
        # どの変換色のオプションが選択されたかを確認するため
        # 信号を送信したチェックボックスを取得
        which_checkbox = self.sender()
        if state == QtCore.Qt.Unchecked:
            self.insert_msg_to_disp(
                "ユーザーは{}色の背景の画像を不要としました".format(which_checkbox.text()))
            self.bg_color_chose_l.remove(which_checkbox.text())
        if state == QtCore.Qt.Checked:
            self.insert_msg_to_disp(
                "ユーザーは{}色の背景の画像を希望しています".format(which_checkbox.text()))
            self.bg_color_chose_l.append(which_checkbox.text())
        if len(self.bg_color_chose_l) == 0:
            self.insert_msg_to_disp("現在、背景が選択されていません!")
        else:
            self.insert_msg_to_disp(
                "現在ユーザーが希望する背景色は:{}".format(self.bg_color_chose_l)

効果は以下の通りです:

image

参考記事:PyQt5 ノート - チェックボックス

ページの更新#

プログラムがカクつく可能性のある場所、特にforループの最初の行にこのコマンドを追加します:

QtWidgets.QApplication.processEvents()

最終効果#

** 注意、実際の使用時に画像の背景が非常に複雑な場合、背景を正常に削除できないことがあります。**

** error.logに以下のエラーが報告されます:**

ERROR:root:Unable to save C:\Users\soapffz\Desktop\xdx.jpg_no_bg.png due to could not identify foreground in image. for details and recommendations see https://www.remove.bg/supported-images.

** したがって、実験にはあまり複雑な画像を選択しないでください。できるだけ背景がそれほど複雑でない人物画像を選択してください。**

単一ファイル変換の最終効果は以下の通りです:

image

複数ファイル変換の最終効果は以下の通りです:

image

本文完。(徹夜して 2 時半まで)


完成品ダウンロードリンク(今後の更新はここに掲載します):

(2019-07-24 午前 2 時半):https://www.lanzous.com/i54q96f

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。