<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-7359781935835547652</id><updated>2024-10-05T13:09:24.370+09:00</updated><category term="linux"/><category term="arch"/><category term="puppy"/><category term="raspberry pi"/><category term="servoblaster"/><category term="gtkdialog"/><category term="robot"/><category term="mouse"/><category term="quadruped"/><category term="doubleclick"/><category term="scratch"/><category term="archbang"/><category term="idesk"/><category term="lubuntu"/><category term="opencv"/><category term="xinitrc"/><category term="ppm"/><category term="windmanager"/><category term="xfce"/><category term="fcraft"/><category term="fluxbox"/><category term="kde"/><category term="ndiswrapper"/><category term="zenity"/><category term="conky"/><title type='text'>コマンドが見つかりません</title><subtitle type='html'>Windowsユーザが古いPCをLinuxで使ってみるアレコレ</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://aoo10yan.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7359781935835547652/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://aoo10yan.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/7359781935835547652/posts/default?start-index=26&amp;max-results=25&amp;redirect=false'/><author><name>AO_o10yan</name><uri>http://www.blogger.com/profile/00449541977510719198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>87</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7359781935835547652.post-7126739802790568807</id><published>2020-03-07T10:59:00.002+09:00</published><updated>2023-09-20T15:06:32.317+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="linux"/><title type='text'>WebSocketでチャット（Tornadoを使う）</title><content type='html'>暇なので、WebSocketでチャットしてみた。&lt;br /&gt;
（Tornadoを使う）&lt;br /&gt;
クライアントからアクセスするIPアドレスやポートは適当に変更する。&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style=&quot;color: red;&quot;&gt;※追記3（2020/03/09　20:40）※&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
HTTPとWebSocketサーバを一つにしてみた。&lt;br /&gt;
&lt;br /&gt;
サーバ（HTTPサーバ及びWebSocketサーバ）&lt;br /&gt;
例えば：tornado_server.py　というファイル名にする。&lt;br /&gt;
このファイルを置いたディレクトリに　templates　と　static　という名の子ディレクトリを作っておく。&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-py linenums&quot;&gt;#!/usr/bin/env python
#-*- coding:utf-8 -*-

import tornado.ioloop
import tornado.web
import tornado.websocket
import datetime
import os.path

cl = []
dic = {}
todaydetail = datetime.datetime.today()
today = todaydetail.strftime(&quot;%Y_%m_%d&quot;)
print(today)
today_log = str(today) + &quot;_log.txt&quot;
print(today_log)
if not os.path.exists(today_log):
    f = open(today_log, &quot;w&quot;)

#クライアントからメッセージを受けるとopen → on_message → on_closeが起動する
class WebSocketHandler(tornado.websocket.WebSocketHandler):
    def check_origin(self, origin):
        return True

    #websocketオープン
    def open(self):
        print(&quot;open&quot;)
        if self not in cl:
            cl.append(self)
            print(len(dic))
            dic[self] = len(dic) 
            print(self)

            f = open(today_log, &quot;r&quot;)
            for row in f:
                self.write_message(row.strip())
            f.close()

            self.write_message(&quot;Welcome !;;&quot;)
 
    #処理
    def on_message(self, message):
        print(&quot;on_message&quot;)
        mess = str(message) + &quot;; ID=&quot; + str(self)[37:47]
        f = open(today_log, &quot;a&quot;)
        f.write(mess + &quot;\n&quot;)
        f.close()

        for client in cl:
            print(str(self))
            print(message)
            #クライアントへメッセージを送信
            client.write_message(mess)
 
    #websockeクローズ
    def on_close(self):
        print(&quot;close&quot;)
        if self in cl:
            cl.remove(self)

#HTTPサーバ
class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.render(&quot;index.html&quot;)

app = tornado.web.Application([
    (r&quot;/&quot;, MainHandler),
    (r&quot;/websocket&quot;, WebSocketHandler),
    ],

    #HTTPサーバで使うpathを設定
    template_path = os.path.join(os.getcwd(),  &quot;templates&quot;),
    static_path = os.path.join(os.getcwd(),  &quot;static&quot;),
)

if __name__ == &quot;__main__&quot;:
   app.listen(8888)
   tornado.ioloop.IOLoop.instance().start()

&lt;/pre&gt;&lt;br /&gt;
インデックス&lt;br /&gt;
index.html　と言うファイル名にする。これを　templates　ディレクトリに置く。&lt;br /&gt;
HTTPサーバにアクセスすると、この　index.html　が呼ばれる。&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-html linenums&quot;&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
&amp;lt;meta charset=&quot;utf-8&quot;/&amp;gt;
&amp;lt;meta name=&quot;viewport&quot; content=&quot;width=device-width,
 initial-scale=1.0,user-scalable=yes&quot; /&amp;gt;
&amp;lt;/head&amp;gt;
 &amp;lt;body&amp;gt;
  Tornado is awesome !&amp;lt;br&amp;gt;
  &amp;lt;a href=&quot;{{static_url(&quot;websocket_chat_client.html&quot;)}}&quot;&amp;gt;Chat Client&amp;lt;/a&amp;gt;
 &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;

&lt;/pre&gt;&lt;br /&gt;
クライアント&lt;br /&gt;
websocket_chat_client.html　と言うファイル名にする。これを　static　ディレクトリに置く。&lt;br /&gt;
インデックスのリンクから呼び出される。&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-html linenums&quot;&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
&amp;lt;meta charset=&quot;utf-8&quot;/&amp;gt;
&amp;lt;meta name=&quot;viewport&quot; content=&quot;width=device-width,
  initial-scale=1.0,user-scalable=yes&quot; /&amp;gt;
&amp;lt;title&amp;gt;WebSocketでチャットしてみよう&amp;lt;/title&amp;gt;
&amp;lt;style&amp;gt;
    #name{
        width:100px;
        height:20px;
    }

    #message{
        width:250px;
        height:20px;
    }
&amp;lt;/style&amp;gt;
&amp;lt;script langage=&quot;JavaScript&quot;&amp;gt;
    ws = new WebSocket(&quot;ws://192.168.1.11:8888/websocket&quot;);

    ws.onopen = function(e) {
//  ws.send(&quot;Hi Open; &quot;);
    }

    ws.onmessage = function(e) {
        var mon = document.getElementById(&quot;monitor&quot;);
        var mes = e.data;
        mes_line = mes.split(&quot;;&quot;);

        var div = document.createElement(&quot;div&quot;);
        mon.appendChild(div);
        div.style.width = &quot;500px&quot;;
        div.style.padding = &quot;10px 10px 10px 10px&quot;;
        div.style.margin = &quot;10px 0px 10px 0px&quot;;
        div.style.border = &quot;solid 1px #0000ff&quot;;
        var div_att = &quot;&amp;lt;div class=&#39;mess&#39; style=&#39;overflow:auto;padding:5px 5px 5px 15px&#39;&amp;gt;&quot;;
        div.innerHTML = mes_line[0] + mes_line[2] + div_att + mes_line[1] + &quot;&amp;lt;/div&amp;gt;&quot;;

//alert(document.body.clientHeight);
        var c_height = document.body.clientHeight;
        if(mes_line[0] == &quot;Welcome !&quot;){
            c_height = 0;
        }
        window.scrollTo(0, c_height);
    }

    function button00(mes){
        var weeks = new Array(&#39;日&#39;,&#39;月&#39;,&#39;火&#39;,&#39;水&#39;,&#39;木&#39;,&#39;金&#39;,&#39;土&#39;);
        var now = new Date();

        var year = now.getYear(); // 年
        var month = now.getMonth() + 1; // 月
        var day = now.getDate(); // 日
        var week = weeks[ now.getDay() ]; // 曜日
        var hour = now.getHours(); // 時
        var min = now.getMinutes(); // 分
        var sec = now.getSeconds(); // 秒

        if(year &amp;lt; 2000) { year += 1900; }

        // 数値が1桁の場合、頭に0を付けて2桁で表示する指定
        if(month &amp;lt; 10) { month = &quot;0&quot; + month; }
        if(day &amp;lt; 10) { day = &quot;0&quot; + day; }
        if(hour &amp;lt; 10) { hour = &quot;0&quot; + hour; }
        if(min &amp;lt; 10) { min = &quot;0&quot; + min; }
        if(sec &amp;lt; 10) { sec = &quot;0&quot; + sec; }

        var now_date = year + &quot;/&quot; + month + &quot;/&quot; + day + &quot;(&quot; + week + &quot;)&quot;;
        var now_time = hour + &quot;:&quot; + min + &quot;:&quot; + sec;
        var nam = document.getElementById(&quot;name&quot;).value;
        ws.send(nam + &quot; &quot; + now_date + &quot; &quot; + now_time + &quot;;&quot; + mes);

        document.getElementById(&quot;message&quot;).value = &quot;&quot;;
    }

&amp;lt;/script&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;h1&amp;gt;WebSocketでチャットしてみよう&amp;lt;/h1&amp;gt;
&amp;lt;h3&amp;gt;メッセージ&amp;lt;/h3&amp;gt;
&amp;lt;div id=&quot;monitor&quot;&amp;gt;&amp;lt;/div&amp;gt;

&amp;lt;p&amp;gt;
表示する名前
&amp;lt;input type=&quot;text&quot; id=&quot;name&quot; value=&quot;ななし&quot; class=&quot;name&quot; /&amp;gt;
&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;
&amp;lt;input type=&quot;text&quot; id=&quot;message&quot; value=&quot;text&quot; class=&quot;message&quot;/&amp;gt;
&amp;lt;button onClick=&quot;button00(document.getElementById(&#39;message&#39;).value)&quot;&amp;gt;送信&amp;lt;/button&amp;gt;
&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;
※　WebSocketのテストです　※
&amp;lt;/p&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;

&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://aoo10yan.blogspot.com/feeds/7126739802790568807/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://aoo10yan.blogspot.com/2020/03/websocket.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7359781935835547652/posts/default/7126739802790568807'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7359781935835547652/posts/default/7126739802790568807'/><link rel='alternate' type='text/html' href='http://aoo10yan.blogspot.com/2020/03/websocket.html' title='WebSocketでチャット（Tornadoを使う）'/><author><name>AO_o10yan</name><uri>http://www.blogger.com/profile/00449541977510719198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7359781935835547652.post-7078933305919427468</id><published>2018-09-06T20:56:00.000+09:00</published><updated>2020-03-24T18:10:16.353+09:00</updated><title type='text'>MNISTは「重心」が重要</title><content type='html'>scikit-learnの手書き数字認識で、MNISTのデータを使ってみることにした。&lt;br /&gt;
先ずは、どんな数字の画像データなのか現物確認しないと始まらないので、MNISTデータを&lt;br /&gt;
画像に落とすスクリプトを書いた。&lt;br /&gt;
どうせなら、先に作ったスクリプトで使えるファイル名で画像保存する。&lt;br /&gt;
&lt;br /&gt;
&quot;counter_limit&quot;で各数字ごとに保存する件数を指定。&lt;br /&gt;
下の例だと、「0」1,000件、「1」1,000件、、、「9」1,000件、と合計10,000件の画像が保存される。&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-py linenums&quot;&gt;#!/usr/bin/env python
# -*- coding: utf-8 -*-

import numpy as np
from sklearn import datasets
import cv2, os

counter = [&#39;&#39;] * 10
counter_limit = 1000

try:
    os.mkdir(&#39;mnist_img&#39;)
except:
    pass

for i in range (0, 10):
    counter[i] = 0
    try:
        os.mkdir(str(i) + &#39;test&#39;)
    except:
        continue


mnist = datasets.fetch_mldata(&#39;MNIST original&#39;)
X, Y = mnist.data,mnist.target

for i in range(0, 70000):
    for n in range(0, 10):
        if Y[i] == n:
            counter[n] += 1
            if counter[n] &amp;lt;= counter_limit:
                img =255 - X[i].reshape(28,28)
                #cv2.imshow(&#39;mnist&#39;, img)
                #k = cv2.waitKey()
                print(&#39;i = &#39; + str(i) + &#39;, target = &#39; + str(Y[i]))

                save_name0 = &#39;./&#39; + str(n) + &#39;test/&#39; + str(counter[n] * 10 + n) + &#39;test.png&#39;
                cv2.imwrite(save_name0, img)

                save_name1 = &#39;./mnist_img/&#39; + str(counter[n] * 10 + n) + &#39;test.png&#39;
                cv2.imwrite(save_name1, img)

&lt;/pre&gt;&lt;br /&gt;
因みに、70,000件全ての画像を保存するには&quot;counter_limit&quot;を（余裕を見て）&quot;counter_limit = 8000&quot;とかにする。&lt;br /&gt;
そうすると、各数字に以下の件数の画像が保存される。&lt;br /&gt;
&lt;br /&gt;
0：6903&lt;br /&gt;
1：7877&lt;br /&gt;
2：6990&lt;br /&gt;
3：7141&lt;br /&gt;
4：6824&lt;br /&gt;
5：6313&lt;br /&gt;
6：6876&lt;br /&gt;
7：7293&lt;br /&gt;
8：6825&lt;br /&gt;
9：6958&lt;br /&gt;
&lt;br /&gt;
さて、保存した画像を眺めると、書かれた数字はバラエティがあるように見えるが、意外と偏っていて、&lt;br /&gt;
描画領域については広範に描かれている訳ではなさそうだ。&lt;br /&gt;
&lt;br /&gt;
例えば、&lt;br /&gt;
「7」は28x28の上部に余白が多い&lt;br /&gt;
「6」だと28x28の下部に余白が多い&lt;br /&gt;
「4」が右に寄っているように見える（縦棒が中心より右に書かれている傾向にあるから）&lt;br /&gt;
「9」も28x28の上部に余白がある&lt;br /&gt;
等々。&lt;br /&gt;
ちょっと見ただけでも上記のような偏り（傾向）が分かる。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgtp5FOkIFqsUBp_CTdpqzGhQwX-hYdjnnqwY4N7JOdpfoxUTOTH-Etq7T2RpOZz_7aYZWiahON4x1qPNtv0KRx-cAzius3_haniDOooZxBVQQN4shGZoNbgFanMC-C8GVWVBA9SQYRUrGT/s1600/2018-09-07--1536330652_821x628_scrot.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;628&quot; data-original-width=&quot;821&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgtp5FOkIFqsUBp_CTdpqzGhQwX-hYdjnnqwY4N7JOdpfoxUTOTH-Etq7T2RpOZz_7aYZWiahON4x1qPNtv0KRx-cAzius3_haniDOooZxBVQQN4shGZoNbgFanMC-C8GVWVBA9SQYRUrGT/s1600/2018-09-07--1536330652_821x628_scrot.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
ただ、これには訳がある。&lt;br /&gt;
&lt;a href=&quot;http://yann.lecun.com/exdb/mnist/&quot;&gt;MNISTを公開しているサイト&lt;/a&gt;に以下の記述がある。&lt;br /&gt;
&lt;blockquote class=&quot;tr_bq&quot;&gt;the images were centered in a 28x28 image by computing the center of mass of the pixels, and translating the image so as to position this point at the center of the 28x28 field.&lt;/blockquote&gt;&lt;b&gt;※次のページが参考になりました。ありがとうございます。&lt;/b&gt;&lt;br /&gt;
&lt;a href=&quot;https://qiita.com/takus69/items/dd904dfc62372310c46f&quot;&gt;「自分の手書きデータをTensorFlowで予測する」&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;https://qiita.com/kaityo256/items/438ee87a0ef1346071b9&quot;&gt;「MNISTを学習させたモデルの気持ちを調べる」&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
「重心」を計算して中央に配置したデータのため、重心が上にあるものは下に移動して&lt;br /&gt;
上部に余白ができる。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWl7-KfX5Cj3tUQU3faCESZSCHMhW0yLSYod1mCvjqdswaF6eji2kq9LVuwzxCerj5NSi-qEN5mFcqTYlVNOL_NDxOhLjwl4gNom6fuyiBVXM5vUqG9RYRgcTpWjOAad467nkfD-szlgGo/s1600/2018-09-08--1536362622_644x570_scrot.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;570&quot; data-original-width=&quot;644&quot; height=&quot;283&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWl7-KfX5Cj3tUQU3faCESZSCHMhW0yLSYod1mCvjqdswaF6eji2kq9LVuwzxCerj5NSi-qEN5mFcqTYlVNOL_NDxOhLjwl4gNom6fuyiBVXM5vUqG9RYRgcTpWjOAad467nkfD-szlgGo/s320/2018-09-08--1536362622_644x570_scrot.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEioa5zh-FBV0rfn-tCLGwiNQYyGULL8GR0OFD3ip60Cgkn19dyBTgv6xZVJVWvenXHG-xmd4uE2uFiBs-144sQdlAnp8KiROodmbA-wb7zS7GLaNnmD_k1PQ-RvBC2yM90Dx1qoqF9gA9Gx/s1600/2018-09-08--1536362874_643x569_scrot.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;569&quot; data-original-width=&quot;643&quot; height=&quot;283&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEioa5zh-FBV0rfn-tCLGwiNQYyGULL8GR0OFD3ip60Cgkn19dyBTgv6xZVJVWvenXHG-xmd4uE2uFiBs-144sQdlAnp8KiROodmbA-wb7zS7GLaNnmD_k1PQ-RvBC2yM90Dx1qoqF9gA9Gx/s320/2018-09-08--1536362874_643x569_scrot.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
重心が下にあるものは上に移動して下部に余白ができる。&lt;br /&gt;
このデータで学習をした場合、同じ様に重心で移動したデータの検証ならば正解率が&lt;br /&gt;
上がるが、そうでないデータでは誤認識が生じやすくなる。&lt;br /&gt;
&lt;br /&gt;
そこで、MNISTのデータで学習をする場合は、それに合わせて判定用データも加工する&lt;br /&gt;
スクリプトを書いてみた。&lt;br /&gt;
前「おまけのおまけ」スクリプト&quot;mnist_img&quot;ディレクトリに置き、引数に28を渡して&lt;br /&gt;
生成した「28x28.csv」を選択すると、MNISTデータでの学習を前提にして判定用データ&lt;br /&gt;
を加工する。&lt;br /&gt;
具体的には&quot;def mnist_mod(img):&quot;の部分がそれにあたる。&lt;br /&gt;
（&lt;strike&gt;横方向の移動に関しては、重心が中央よりも右方向に行くようにしてある。&lt;/strike&gt;）&lt;br /&gt;
&lt;b&gt;&lt;span style=&quot;color: red;&quot;&gt;※追記1（2018/09/09　10:00）※&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&quot;def mnist_mod(img):&quot;の重心移動方法を修正。&lt;br /&gt;
&lt;b&gt;&lt;span style=&quot;color: red;&quot;&gt;※追記2（2018/09/10　22:00）※&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
digits.csv用の前処理を追加したつもり。&lt;br /&gt;
&lt;b&gt;&lt;span style=&quot;color: red;&quot;&gt;※追記3（2018/09/12　20:10）※&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
縦横比が同じでないテスト用画像の読み込みに対応したつもり。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfn64qYRBEmxDAh3MNBVQxNcvqum9p0J6IUNx4vlGPCZ2G2uIfsHuo-IgZ0S_w7hoYfBJ6Ydh833auMVXSOypvlzbZJ6bj-LoeUQz7vxqx2fcYtLvLQUoA7s38uweLDFUvyaGIPCOEjN-I/s1600/2018-09-12--1536749998_645x562_scrot.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;562&quot; data-original-width=&quot;645&quot; height=&quot;278&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfn64qYRBEmxDAh3MNBVQxNcvqum9p0J6IUNx4vlGPCZ2G2uIfsHuo-IgZ0S_w7hoYfBJ6Ydh833auMVXSOypvlzbZJ6bj-LoeUQz7vxqx2fcYtLvLQUoA7s38uweLDFUvyaGIPCOEjN-I/s320/2018-09-12--1536749998_645x562_scrot.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;現状下の様に、パーツに分かれた数字は、&lt;span style=&quot;color: red;&quot;&gt;&lt;b&gt;重心を求めていない&lt;/b&gt;&lt;/span&gt;ためMNISTの学習結果では、正常に判定できない。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheO37kAQB-QhCwlemVKrfW1pO_YDHnh4Ho6vk-jW6yfeJ9wqlHSxAV0hjGjm9yCtvRETG3szh8qvEseksBZ3130P-3Xo1ENWkt1BLzmK_mYH3jhzlhA_8hLkD9QKNvXE1oUVLmqI5UmQde/s1600/2018-09-12--1536750273_261x155_scrot.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;155&quot; data-original-width=&quot;261&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheO37kAQB-QhCwlemVKrfW1pO_YDHnh4Ho6vk-jW6yfeJ9wqlHSxAV0hjGjm9yCtvRETG3szh8qvEseksBZ3130P-3Xo1ENWkt1BLzmK_mYH3jhzlhA_8hLkD9QKNvXE1oUVLmqI5UmQde/s1600/2018-09-12--1536750273_261x155_scrot.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;b&gt;&lt;span style=&quot;color: red;&quot;&gt;※追記4（2018/09/14　20:30）※&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
パーツに分かれた数字の重心（と言うか画像の重心）を求めるように修正。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPHBANjkNATLrRFiwbQ0doCZQ3Nrlc0NUGbfsCgA7_SQUFpa03gsaDOGqovP9pb83cYUgSi6vg60mebqfLgnuN7Jn6j_ChUmOYk6OCzHivylj3nIxZUJXof0FQpQi6CsOIxRpWC7cajsd1/s1600/2018-09-14--1536924268_243x144_scrot.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;144&quot; data-original-width=&quot;243&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPHBANjkNATLrRFiwbQ0doCZQ3Nrlc0NUGbfsCgA7_SQUFpa03gsaDOGqovP9pb83cYUgSi6vg60mebqfLgnuN7Jn6j_ChUmOYk6OCzHivylj3nIxZUJXof0FQpQi6CsOIxRpWC7cajsd1/s1600/2018-09-14--1536924268_243x144_scrot.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
ある程度の調整は出きるが、、、。うーん、今一。&lt;br /&gt;
ちなみに分類機のパラメータは出鱈目なので悪しからず。&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqymS_gdYjHF4XdOsqEl8TERJsm6YrNEcnNByTJ40PvQvrEYhXHbAotLS2h9pZH_J3RHc2b7w20oBP-nyeAhzwdbieHu6L84tRFilJknvoSDfr6qJ_TBomt_TW3w4lCMW_npac78RL7Oai/s1600/2018-09-09--1536455498_641x569_scrot.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;569&quot; data-original-width=&quot;641&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqymS_gdYjHF4XdOsqEl8TERJsm6YrNEcnNByTJ40PvQvrEYhXHbAotLS2h9pZH_J3RHc2b7w20oBP-nyeAhzwdbieHu6L84tRFilJknvoSDfr6qJ_TBomt_TW3w4lCMW_npac78RL7Oai/s1600/2018-09-09--1536455498_641x569_scrot.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;b&gt;&lt;span style=&quot;color: red;&quot;&gt;※追記5（2019/12/05　11:10）※&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
OpenCVのバージョンにより、findContoursの返り値の数が異なる事に対応（？）。&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-py linenums&quot;&gt;#!/usr/bin/env python
# -*- coding: utf-8 -*-

import matplotlib.pyplot as plt
import numpy as np
import cv2
from time import sleep
from os.path import dirname, join, basename, exists
from sklearn.datasets.base import Bunch
import sys
from sklearn.externals import joblib

py_version = sys.version_info.major
cv_version = cv2.__version__[0:1]
module_path = dirname(__file__)

if py_version != 2:
    import tkinter as tk, tkinter.filedialog as tkfiledialog, tkinter.messagebox as tkmessage, \
           tkinter.simpledialog as tksimpledialog
else:
    import Tkinter as tk, tkFileDialog  as tkfiledialog, tkMessageBox as tkmessage, \
           tkSimpleDialog as tksimpledialog

def clf_select():
    def check():
        root.quit()
        return v.get()

    root = tk.Tk()
    root.title(&#39;digit_test&#39;)

    v = tk.IntVar()
    v.set(0)

    radio1 = tk.Radiobutton(text=&#39;SVM&#39;, variable=v, value=1, font=(&quot;&quot;,14))
    radio1.pack(anchor=&#39;w&#39;)

    radio2 = tk.Radiobutton(text=&#39;MLPClassifier&#39;, variable=v, value=2, font=(&quot;&quot;,14))
    radio2.pack(anchor=&#39;w&#39;)

    radio3 = tk.Radiobutton(text=&#39;LogisticRegression&#39;, variable=v, value=3, font=(&quot;&quot;,14))
    radio3.pack(anchor=&#39;w&#39;)

    radio4 = tk.Radiobutton(text=&#39;DecisionTreeClassifier&#39;, variable=v, value=4, font=(&quot;&quot;,14))
    radio4.pack(anchor=&#39;w&#39;)

    button1 = tk.Button(root, text=&#39;決　定&#39;, command= lambda: check(), width=30, font=(&quot;&quot;,14))
    button1.pack()

    root.mainloop()
    try:
        root.destroy()
    except:
        sys.exit()

    return check()

def csv_select():
    root = tk.Tk()
    root.withdraw()

    file_type = [(&#39;&#39;, &#39;*csv&#39;)]
    data_path = join(dirname(__file__), &#39;data&#39;)
    tkmessage.showinfo(&#39;digit_test&#39;, &#39;データ(csv)を選択してください&#39;)
    test_csv = tkfiledialog.askopenfilename(filetypes=file_type, initialdir=data_path)
    if test_csv == () or test_csv == &#39;&#39;:
        test_csv = &#39;digits.csv&#39;
    else:
        test_csv = basename(test_csv)

    root.destroy()
    print(test_csv)
    return test_csv

def img_select():
    root = tk.Tk()
    root.withdraw()

    file_type = [(&#39;&#39;, &#39;*png&#39;)]
    data_path = dirname(__file__)
    #tkmessage.showinfo(test_csv, &#39;画像(png)を選択してください&#39;)
    test_img = tkfiledialog.askopenfilename(filetypes=file_type, initialdir=data_path)
    if test_img == () or test_img == &#39;&#39;:
        test_img = &#39;digit_test.png&#39;

    root.destroy()
    print(test_img)
    return test_img

def question0():
    root = tk.Tk()
    root.withdraw()

    y_or_n = tkmessage.askquestion(test_csv, &#39;判定は&#39; + str(predicted) + &#39;\n正しいですか？&#39;)

    root.destroy()
    return y_or_n

def question1():
    root = tk.Tk()
    root.withdraw()

    next_y_or_n = tkmessage.askquestion(test_csv, &#39;続けますか？&#39;)

    root.destroy()
    return next_y_or_n

def correct_input():
    root = tk.Tk()
    root.withdraw()
    root.after(1, lambda: root.focus_force())
    correct_digit = tksimpledialog.askinteger(test_csv, &#39;正解を教えてください&#39;, 
                                              initialvalue=&#39;ここに入力&#39;,parent=root)

    root.destroy()
    return correct_digit

def load_digits():
    module_path = dirname(__file__)
    data = np.loadtxt(join(module_path, &#39;data&#39;, test_csv),
                      delimiter=&#39;,&#39;)

    data_len = int(np.sqrt(len(data[0]) - 1))

    target = data[:, -1].astype(np.int)
    flat_data = data[:, :-1]
    images = flat_data.view()
    images.shape = (-1, data_len, data_len)

    return Bunch(data=flat_data,
                 target=target,
                 target_names=np.arange(10),
                 images=images)

def pre_mod(img):
    data_len = int(np.sqrt(len(data[0])))
    size = (data_len, data_len)
    temp_h, temp_w = img.shape[:2]

    if temp_w &amp;gt; temp_h:
        temp_size = temp_w
    else:
        temp_size = temp_h

    if test_csv == &#39;28x28.csv&#39;:
        temp_scale = 0.79
    elif test_csv == &#39;digits.csv&#39;:
        temp_scale = 1
    else:
        temp_scale = 0.9

    temp_re_size = temp_size + 2

    img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    img = np.round(255 - img)
    M = np.float32([[1,0,1],[0,1,1]])
    img = cv2.warpAffine(img, M, (temp_re_size, temp_re_size))
    img = np.round(255 - img)

    ret,thresh = cv2.threshold(img, 50, 255, 0)
    if cv_version == &#39;3&#39;:
        imgEdge,contours,hierarchy = cv2.findContours(thresh, cv2.RETR_LIST,
                                                      cv2.CHAIN_APPROX_SIMPLE)
    else:
        contours,hierarchy = cv2.findContours(thresh, cv2.RETR_LIST,
                                              cv2.CHAIN_APPROX_SIMPLE)

    x_locale = []
    y_locale = []
    if len(contours) &amp;gt; 2:
        n = len(contours) - 1
    else:
        n = 1

    for i in range(0, n):
        x,y,w,h = cv2.boundingRect(contours[i])
        x_locale.append(x)
        x_locale.append(x + w)
        y_locale.append(y)
        y_locale.append(y + h)
    x = min(x_locale)
    y = min(y_locale)
    w = max(x_locale) - min(x_locale)
    h = max(y_locale) - min(y_locale)
    img = img[y:y+h, x:x+w]

    if h &amp;gt;= w:
        r_scale_x = int(w * data_len * temp_scale / h)
        r_scale_y = int(data_len * temp_scale)
    else:
        r_scale_x = int(data_len * temp_scale)
        r_scale_y = int(h * data_len * temp_scale / w)

    img = cv2.resize(img, (r_scale_x, r_scale_y), interpolation=cv2.INTER_AREA)
    img = np.round(255 - img)

    if test_csv == &#39;28x28.csv&#39;:
        M = np.float32([[1,0,1],[0,1,1]])
        img = cv2.warpAffine(img, M, (r_scale_x + 2, r_scale_y + 2))

        M = cv2.moments(img)
        cx = int(M[&#39;m10&#39;]/M[&#39;m00&#39;]) + 1
        cy = int(M[&#39;m01&#39;]/M[&#39;m00&#39;]) + 1

    else:
        cx = int(r_scale_x / 2)
        cy = int(r_scale_y / 2)

    print(cx, cy)

    xc = int(data_len / 2) - cx
    yc = int(data_len / 2) - cy
    print(xc, yc)
    M = np.float32([[1,0,xc],[0,1,yc]])
    img = cv2.warpAffine(img, M, size)
    img = np.round(img / 16)
    return img


test_clf = clf_select()
if test_clf == 1:
    print(&#39;SVM&#39;)
    from sklearn import svm
    clf_name = &#39;svm&#39;
    classifier = svm.SVC(C=10, gamma=&#39;scale&#39;)
elif test_clf == 2:
    print(&#39;MLPClassifier&#39;)
    from sklearn.neural_network import MLPClassifier
    clf_name = &#39;mlp&#39;
    classifier = MLPClassifier(hidden_layer_sizes=(256, 128, 64, 64, 10),
                               verbose=True, alpha=0.001,
                               max_iter=10000, tol=0.00001, random_state=1)
elif test_clf == 3:
    print(&#39;LogisticRegression&#39;)
    from sklearn.linear_model import LogisticRegression
    clf_name = &#39;lr&#39;
    classifier = LogisticRegression()
elif test_clf == 4:
    print(&#39;DecisionTreeClassifier&#39;)
    from sklearn.tree import DecisionTreeClassifier
    clf_name = &#39;dt&#39;
    classifier = DecisionTreeClassifier()
else:
    sys.exit()

test_csv = csv_select()
test_img = img_select()

if exists(&#39;./&#39; + test_csv + &#39;.&#39; + clf_name + &#39;.pkl&#39;):
    y_or_n = &#39;&#39;
    #y_or_n = &#39;no&#39;
else:
    y_or_n = &#39;no&#39;

while(True):
    digits = load_digits()
    n_samples = len(digits.images)
    data = digits.images.reshape((n_samples, -1))

    if y_or_n == &#39;no&#39;:
        print(classifier)
        classifier.fit(data, digits.target)
        joblib.dump(classifier, test_csv + &#39;.&#39; + clf_name + &#39;.pkl&#39;, compress=True)
    else:
        classifier = joblib.load(test_csv + &#39;.&#39; + clf_name + &#39;.pkl&#39;)

    images_and_labels = list(zip(digits.images, digits.target))
    for index, (image, label) in enumerate(images_and_labels[:10]):
        plt.subplot(3, 5, index + 1)
        plt.axis(&#39;on&#39;)
        plt.imshow(image, cmap=plt.cm.gray_r, interpolation=&#39;nearest&#39;)
        plt.title(&#39;Training %i&#39; % label)

    img = cv2.imread(test_img)
    grayim = pre_mod(img)
    im = grayim

    print(grayim)
    grayim = grayim.reshape(1, -1)
    np.savetxt(&#39;digit_test.csv&#39;, grayim, delimiter = &#39;,&#39;, fmt = &#39;%.0f&#39;)

    predicted = classifier.predict(grayim)
    print(&#39;判定は、&#39; + str(predicted))

    plt.subplot(3, 5, 11)
    plt.axis(&#39;on&#39;)
    plt.imshow(img, cmap=plt.cm.gray_r, interpolation=&#39;nearest&#39;)
    plt.title(&#39;Original&#39;)
    plt.subplot(3, 5, 12)
    plt.axis(&#39;on&#39;)
    plt.imshow(im, cmap=plt.cm.gray_r, interpolation=&#39;nearest&#39;)
    plt.title(&#39;Prodicted %i&#39; % predicted)
    plt.show()

    y_or_n = question0()

    if y_or_n == &#39;no&#39;:
        correct_digit = correct_input()
        if correct_digit != None:
            grayim = np.append(grayim, correct_digit)
            grayim = grayim.reshape(1, -1)

            f = open(join(module_path, &#39;data&#39;, test_csv), &#39;a&#39;)
            np.savetxt(f, grayim, delimiter = &#39;,&#39;, fmt = &#39;%.0f&#39;)
            f.close()
            sleep(1)
        else:
            correct_digit = str(predicted[0])
    else:
        next_y_or_n = question1()

        if next_y_or_n == &#39;no&#39;:
            sys.exit()

        test_img = img_select()

&lt;/pre&gt;&lt;br /&gt;
</content><link rel='replies' type='application/atom+xml' href='http://aoo10yan.blogspot.com/feeds/7078933305919427468/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://aoo10yan.blogspot.com/2018/09/mnist.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7359781935835547652/posts/default/7078933305919427468'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7359781935835547652/posts/default/7078933305919427468'/><link rel='alternate' type='text/html' href='http://aoo10yan.blogspot.com/2018/09/mnist.html' title='MNISTは「重心」が重要'/><author><name>AO_o10yan</name><uri>http://www.blogger.com/profile/00449541977510719198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgtp5FOkIFqsUBp_CTdpqzGhQwX-hYdjnnqwY4N7JOdpfoxUTOTH-Etq7T2RpOZz_7aYZWiahON4x1qPNtv0KRx-cAzius3_haniDOooZxBVQQN4shGZoNbgFanMC-C8GVWVBA9SQYRUrGT/s72-c/2018-09-07--1536330652_821x628_scrot.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7359781935835547652.post-8144599708845914225</id><published>2018-08-20T21:35:00.000+09:00</published><updated>2020-03-10T09:04:02.265+09:00</updated><title type='text'>scikit-learn おまけの話（おまけ付き）</title><content type='html'>scikit-learn付属のdigits.csvを使ってみたが、手書き数字の認識をしたいなら、別のデザインの方が良いだろう。&lt;br /&gt;
&lt;br /&gt;
「手書き数字の認識　→　scikit-learn」ではなくて、「scikit-learnの演習　→　手書き数字の認識例を使用」&lt;br /&gt;
である事を忘れると、勘違いが生じる。 &lt;br /&gt;
&lt;br /&gt;
と、書きながらも勘違いのスクリプトをあげる。&lt;br /&gt;
&lt;a href=&quot;http://aoo10yan.blogspot.com/2018/08/scikit-learn.html&quot;&gt;前回と同じ動作&lt;/a&gt;の、scikit-learnを使った数字認識のスクリプトだが、tkinterを使ってみた。&lt;br /&gt;
データのcsvファイルの選択、判定する画像pngファイルの選択ダイアログやメッセージ等がtkinterで表示される。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEii02OimavfFbXlncQrDeHSS9oa2ifuqLtJcwIG3lR2_eiFpM1tAjxf382ijUT_dVc7W9p0bnU1UNgx9PRr2YASA61Kdq5nGB-Kva2LJdi6Ue_wXBDFjoT_aAKFN2qxZzn5pIzR4yJnsfjR/s1600/2018-08-20--1534768054_434x305_scrot.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;305&quot; data-original-width=&quot;434&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEii02OimavfFbXlncQrDeHSS9oa2ifuqLtJcwIG3lR2_eiFpM1tAjxf382ijUT_dVc7W9p0bnU1UNgx9PRr2YASA61Kdq5nGB-Kva2LJdi6Ue_wXBDFjoT_aAKFN2qxZzn5pIzR4yJnsfjR/s1600/2018-08-20--1534768054_434x305_scrot.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwXleknV47mar2lhg4AJ_3iduTLJgMSpgN82f7UO26-KBNgoKQVViVk5H2ZHoUhVQ1lYohtltOTUHcHszdcz9erx-s38SYeoh_cWvQCSiVRL_mAwfy2qkbhw1iUtJsRxhnH0BHbjbdpWTY/s1600/2018-08-20--1534768111_208x151_scrot.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;151&quot; data-original-width=&quot;208&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwXleknV47mar2lhg4AJ_3iduTLJgMSpgN82f7UO26-KBNgoKQVViVk5H2ZHoUhVQ1lYohtltOTUHcHszdcz9erx-s38SYeoh_cWvQCSiVRL_mAwfy2qkbhw1iUtJsRxhnH0BHbjbdpWTY/s1600/2018-08-20--1534768111_208x151_scrot.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhguoq5cwquC40JrEDwz4P2RvC3rUVyQCIMskC39GnXFNIcC4Qd15EJm6li-Y2wf-EERkuq0OR9hW8170RmfeyjadPGQoOF4e-oEDjmOW7PfG_geDkYwS7Ii83ucUVPnlr_pvEgIVqrXSp8/s1600/2018-08-20--1534768135_240x152_scrot.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;152&quot; data-original-width=&quot;240&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhguoq5cwquC40JrEDwz4P2RvC3rUVyQCIMskC39GnXFNIcC4Qd15EJm6li-Y2wf-EERkuq0OR9hW8170RmfeyjadPGQoOF4e-oEDjmOW7PfG_geDkYwS7Ii83ucUVPnlr_pvEgIVqrXSp8/s1600/2018-08-20--1534768135_240x152_scrot.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;b&gt;&lt;span style=&quot;color: red;&quot;&gt;※追記1（2018/08/21　14:30）※&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
分類器を保存するようにした。&lt;br /&gt;
スクリプトでは分類器の保存ファイルが存在すれば、それを使うようにしているが、&lt;br /&gt;
実際問題としては&lt;b&gt;&lt;span style=&quot;color: red;&quot;&gt;意味が無い&lt;/span&gt;&lt;/b&gt;。&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style=&quot;color: red;&quot;&gt;※追記2（2018/08/26　9:30）※ &lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
「8x8=64　+　ラベル」以外に対応するようにした。&lt;br /&gt;
（画像の）縦横比が同じトレーニング用データならば、それに合わせてテスト用画像を&lt;br /&gt;
リサイズして判定する。&lt;br /&gt;
分類器の保存ファイルは実際の判定では使わないように変更。 &lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-py linenums&quot;&gt;#!/usr/bin/env python
# -*- coding: utf-8 -*-

import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.neural_network import MLPClassifier

import numpy as np
import cv2
from time import sleep
from os.path import dirname, join, basename, exists
from sklearn.datasets.base import Bunch
import sys
from sklearn.externals import joblib

py_version = sys.version_info.major

module_path = dirname(__file__)
#print(dirname(abspath(&#39;__file__&#39;)))
#print(module_path)

if py_version != 2:
    import tkinter as tk, tkinter.filedialog as tkfiledialog, tkinter.messagebox as tkmessage, \
           tkinter.simpledialog as tksimpledialog
else:
    import Tkinter as tk, tkFileDialog  as tkfiledialog, tkMessageBox as tkmessage, \
           tkSimpleDialog as tksimpledialog

def csv_select():
    root = tk.Tk()
    root.withdraw()

    file_type = [(&#39;&#39;, &#39;*csv&#39;)]
    data_path = join(dirname(__file__), &#39;data&#39;)
    tkmessage.showinfo(&#39;digit_test&#39;, &#39;データ(csv)を選択してください&#39;)
    test_csv = tkfiledialog.askopenfilename(filetypes=file_type, initialdir=data_path)
    if test_csv == () or test_csv == &#39;&#39;:
        test_csv = &#39;digits.csv&#39;
    else:
        test_csv = basename(test_csv)

    root.destroy()
    #print(test_csv)
    return test_csv

def img_select():
    root = tk.Tk()
    root.withdraw()

    file_type = [(&#39;&#39;, &#39;*png&#39;)]
    #data_path = dirname(abspath(&#39;__file__&#39;))
    data_path = dirname(__file__)
    tkmessage.showinfo(test_csv, &#39;画像(png)を選択してください&#39;)
    test_img = tkfiledialog.askopenfilename(filetypes=file_type, initialdir=data_path)
    #print(dirname(abspath(&#39;__file__&#39;)))
    if test_img == () or test_img == &#39;&#39;:
        test_img = &#39;digit_test.png&#39;

    root.destroy()
    #print(test_img)
    return test_img

def question0():
    root = tk.Tk()
    root.withdraw()

    y_or_n = tkmessage.askquestion(test_csv, &#39;判定は&#39; + str(predicted) + &#39;\n正しいですか？&#39;)

    root.destroy()
    return y_or_n

def question1():
    root = tk.Tk()
    root.withdraw()

    next_y_or_n = tkmessage.askquestion(test_csv, &#39;続けますか？&#39;)

    root.destroy()
    return next_y_or_n

def correct_input():
    root = tk.Tk()
    root.withdraw()
    root.after(1, lambda: root.focus_force())
    correct_digit = tksimpledialog.askinteger(test_csv, &#39;正解を教えてください&#39;, 
                                              initialvalue=&#39;ここに入力&#39;,parent=root)

    root.destroy()
    return correct_digit

def load_digits():
    module_path = dirname(__file__)
    data = np.loadtxt(join(module_path, &#39;data&#39;, test_csv),
                      delimiter=&#39;,&#39;)

    data_len = int(np.sqrt(len(data[0]) - 1))
    #print(data_len)

    target = data[:, -1].astype(np.int)
    flat_data = data[:, :-1]
    images = flat_data.view()
    images.shape = (-1, data_len, data_len)

    return Bunch(data=flat_data,
                 target=target,
                 target_names=np.arange(10),
                 images=images)


test_csv = csv_select()
test_img = img_select()

if exists(&#39;./&#39; + test_csv + &#39;.mlp.pkl&#39;):
    #y_or_n = &#39;&#39;
    y_or_n = &#39;no&#39;
else:
    y_or_n = &#39;no&#39;

while(True):
    digits = load_digits()
    n_samples = len(digits.images)
    data = digits.images.reshape((n_samples, -1))

    if y_or_n == &#39;no&#39;:
        classifier = MLPClassifier(hidden_layer_sizes=(100, 100, 100, 10),
                                   max_iter=10000, tol=0.00001, random_state=1)
        print(classifier)
        classifier.fit(data, digits.target)
        joblib.dump(classifier, test_csv + &#39;.mlp.pkl&#39;, compress=True)
    else:
        classifier = joblib.load(test_csv + &#39;.mlp.pkl&#39;)
        #print(classifier)

    images_and_labels = list(zip(digits.images, digits.target))
    #plt.figure(figsize=(5.5, 3))
    for index, (image, label) in enumerate(images_and_labels[:10]):
        plt.subplot(3, 5, index + 1)
        plt.axis(&#39;off&#39;)
        plt.imshow(image, cmap=plt.cm.gray_r, interpolation=&#39;nearest&#39;)
        plt.title(&#39;Training %i&#39; % label)

    img = cv2.imread(test_img)

    data_len = int(np.sqrt(len(data[0])))
    #print(data_len)

    size = (data_len, data_len)
    im = cv2.resize(img, size, interpolation=cv2.INTER_AREA)

    imgray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
    #print(imgray)
    grayim = np.round((255 - imgray) / 16)
    grayim = grayim.reshape(1, -1)
    print(grayim)
    np.savetxt(&#39;digit_test.csv&#39;, grayim, delimiter = &#39;,&#39;, fmt = &#39;%.0f&#39;)

    predicted = classifier.predict(grayim)
    print(&#39;判定は、&#39; + str(predicted))

    plt.subplot(3, 5, 11)
    plt.axis(&#39;off&#39;)
    plt.imshow(img, cmap=plt.cm.gray_r, interpolation=&#39;nearest&#39;)
    plt.title(&#39;Original&#39;)
    plt.subplot(3, 5, 12)
    plt.axis(&#39;off&#39;)
    plt.imshow(im, cmap=plt.cm.gray_r, interpolation=&#39;nearest&#39;)
    plt.title(&#39;Prodicted %i&#39; % predicted)
    plt.show()

    y_or_n = question0()

    if y_or_n == &#39;no&#39;:
        correct_digit = correct_input()
        if correct_digit != None:
            grayim = np.append(grayim, correct_digit)
            #print(grayim)
            grayim = grayim.reshape(1, -1)

            f = open(join(module_path, &#39;data&#39;, test_csv), &#39;a&#39;)
            np.savetxt(f, grayim, delimiter = &#39;,&#39;, fmt = &#39;%.0f&#39;)
            f.close()
            sleep(1)
        else:
            correct_digit = str(predicted[0])
    else:
        next_y_or_n = question1()

        if next_y_or_n == &#39;no&#39;:
            break

        test_img = img_select()

&lt;/pre&gt;&lt;br /&gt;
&lt;h4&gt;&lt;b&gt;おまけのおまけスクリプト&lt;/b&gt;&lt;/h4&gt;10個の画像から、トレーニング用csvデータを生成するスクリプト。&lt;br /&gt;
スクリプトと同一ディレクトリ内の「0test.png」「1test.png」・・・「9test.png」という&lt;br /&gt;
ファイル名の画像ファイルを、順番に読込み「8x8=64　+　ラベル」の型でcsvファイルを生成する。&lt;br /&gt;
デフォルトでは8x8=64だが、スクリプトの引数に数値を与えるとそれを基にしたデータになる。&lt;br /&gt;
例えば、「5」を引数にすると、「5x5=25　+　ラベル」の型になる。&lt;br /&gt;
（仮にスクリプトのファイル名を「prepare.py」とした場合、「python prepare.py 5」と言った記述） &lt;br /&gt;
&lt;br /&gt;
生成されたcsvは、「5x5.csv」と言うファイル名で同一ディレクトリに保存される。&lt;br /&gt;
これをdataディレクトリへ移動して上のスクリプトで読み込めば、そのデータで分類器を生成してテスト&lt;br /&gt;
画像を判定する。&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style=&quot;color: red;&quot;&gt;※追記3（2018/08/27　11:45）※ &lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
ファイル名からラベルの取り方を変更&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-py linenums&quot;&gt;#!/usr/bin/env python
# -*- coding: utf-8 -*-

import numpy as np
import sys, cv2

args = sys.argv
print(args)
if len(args) &amp;gt; 2:
    print(&#39;引数が多すぎます&#39;)
    sys.exit()
elif len(args) == 2:
    try:
        type(int(args[1])) == int
        pix = int(args[1])
    except ValueError:
        print(&#39;引数の型が違います&#39;)
        sys.exit()
else:
    print(&#39;既定のデータ型を使います&#39;)
    pix = 8

for num in range(0, 10):
    try:
        img_file = str(num) + &#39;test.png&#39;
        im = cv2.imread(img_file)

        size = (pix, pix)
        im = cv2.resize(im, size, interpolation=cv2.INTER_AREA)

        imgray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
        print(imgray)
        grayim = np.round((255 - imgray) / 16)
        grayim = grayim.reshape(1, -1)
        grayim = np.array(grayim, dtype = np.uint8)
        grayim = np.append(grayim, int(str(num)[-1]))
        grayim = grayim.reshape(1, -1)
        print(grayim)

        f = open(str(pix) + &#39;x&#39; + str(pix) + &#39;.csv&#39;, &#39;a&#39;)
        np.savetxt(f, grayim, delimiter = &quot;,&quot;, fmt = &quot;%.0f&quot;)
        f.close()

        #cv2.imshow(str(pix) + &#39;test&#39;, imgray)
        #cv2.waitKey(0)
    except:
        print(str(num) + &#39;test.png をスキップ&#39;)

&lt;/pre&gt;&lt;br /&gt;
10個より多くのデータを生成したい場合は&quot;range(0, 10)&quot;を書き換える&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-py linenums&quot;&gt;for num in range(0, 1000):&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://aoo10yan.blogspot.com/feeds/8144599708845914225/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://aoo10yan.blogspot.com/2018/08/scikit-learn_20.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7359781935835547652/posts/default/8144599708845914225'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7359781935835547652/posts/default/8144599708845914225'/><link rel='alternate' type='text/html' href='http://aoo10yan.blogspot.com/2018/08/scikit-learn_20.html' title='scikit-learn おまけの話（おまけ付き）'/><author><name>AO_o10yan</name><uri>http://www.blogger.com/profile/00449541977510719198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEii02OimavfFbXlncQrDeHSS9oa2ifuqLtJcwIG3lR2_eiFpM1tAjxf382ijUT_dVc7W9p0bnU1UNgx9PRr2YASA61Kdq5nGB-Kva2LJdi6Ue_wXBDFjoT_aAKFN2qxZzn5pIzR4yJnsfjR/s72-c/2018-08-20--1534768054_434x305_scrot.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7359781935835547652.post-2210356041109501188</id><published>2018-08-04T18:42:00.000+09:00</published><updated>2020-03-07T15:36:13.462+09:00</updated><title type='text'>scikit-learnで漢数字認識</title><content type='html'>&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3SJ_vlXghphmsLUqqQQZmZvMxNZM48lVvgyuR-QyEjoxK-9l70UQVs7J9IdSasbq6CTAaioxIdA4X8ggB_FzFx7BecCxgvawWrsunoMqUkIgLHMz4l5eB5r1B0EiFqULw32rIg14spD51/s1600/2018-08-04--1533349935_1280x1024_scrot.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;806&quot; data-original-width=&quot;1064&quot; height=&quot;302&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3SJ_vlXghphmsLUqqQQZmZvMxNZM48lVvgyuR-QyEjoxK-9l70UQVs7J9IdSasbq6CTAaioxIdA4X8ggB_FzFx7BecCxgvawWrsunoMqUkIgLHMz4l5eB5r1B0EiFqULw32rIg14spD51/s400/2018-08-04--1533349935_1280x1024_scrot.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
scikit-learnにサンプルで付いてくる手書き数字認識のデータセットを弄ってみるのが目的。&lt;br /&gt;
&lt;span style=&quot;color: red;&quot;&gt;&lt;b&gt;（※画像の処理にOpenCVを使ってます※） &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
手書き数字のデータ（digits.csv）を書き換えたいので、付属のデータをコピーして使用する。&lt;br /&gt;
&quot;pip&quot;でscikit-learnをインストールした私の環境で、データは以下のディレクトリにある。&lt;br /&gt;
&lt;br /&gt;
※Windowsの場合&lt;br /&gt;
&quot;C:/Users/&amp;lt;username&amp;gt;/AppData/Local/Programs/Python/Python36-32/lib/site-packages/sklearn/datasets/data/digits.csv.gz&quot;&lt;br /&gt;
&lt;br /&gt;
※Arch Linux 32の場合&lt;br /&gt;
&quot;/usr/lib/python3.6/site-packages/sklearn/datasets/data/digits.csv.gz&quot;&lt;br /&gt;
&lt;br /&gt;
予め任意のディレクトリを作成してその中に&quot;data&quot;ディレクトリを作成し、その&quot;data&quot;ディレクトリに &lt;br /&gt;
&quot;digits.csv.gz&quot;をコピーする。更にエディタ等で直接扱いたいので、解凍もしておく。&lt;br /&gt;
データを置いたディレクトリより一つ上の階層に以下のPythonスクリプトを置く。&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-py linenums&quot;&gt;#!/usr/bin/env python
# -*- coding: utf-8 -*-

import matplotlib.pyplot as plt
from sklearn import datasets, svm

import numpy as np
import cv2
from time import sleep
from os.path import dirname, join
from sklearn.datasets.base import Bunch
import sys

y_or_n = &#39;n&#39;
module_path = dirname(__file__)

def load_digits(n_class=10, return_X_y=False):
    module_path = dirname(__file__)
    data = np.loadtxt(join(module_path, &#39;data&#39;, &#39;digits.csv&#39;),
                      delimiter=&#39;,&#39;)
    #with open(join(module_path, &#39;descr&#39;, &#39;digits.rst&#39;)) as f:
    #    descr = f.read()
    target = data[:, -1].astype(np.int)
    flat_data = data[:, :-1]
    images = flat_data.view()
    images.shape = (-1, 8, 8)

    if n_class &amp;lt; 10:
        idx = target &amp;lt; n_class
        flat_data, target = flat_data[idx], target[idx]
        images = images[idx]

    if return_X_y:
        return flat_data, target

    return Bunch(data=flat_data,
                 target=target,
                 target_names=np.arange(10),
                 images=images)
                 #DESCR=descr)


while(True):
    if y_or_n == &#39;n&#39;:
        digits = load_digits()

        n_samples = len(digits.images)
        data = digits.images.reshape((n_samples, -1))

        classifier = svm.SVC(C=100, gamma=0.001)
        print(classifier)
        #classifier.fit(data[:n_samples], digits.target[:n_samples])
        classifier.fit(data, digits.target)

    images_and_labels = list(zip(digits.images, digits.target))
    for index, (image, label) in enumerate(images_and_labels[:10]):
        plt.subplot(3, 5, index + 1)
        plt.axis(&#39;off&#39;)
        plt.imshow(image, cmap=plt.cm.gray_r, interpolation=&#39;nearest&#39;)
        plt.title(&#39;Training %i&#39; % label)

    img = cv2.imread(&#39;digit_test.png&#39;)

    size = (8, 8)
    im = cv2.resize(img, size, interpolation=cv2.INTER_AREA)

    imgray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
    #print(imgray)
    grayim = np.round((255 - imgray) / 16)
    grayim = grayim.reshape(1, -1)
    print(grayim)
    np.savetxt(&#39;digit_test.csv&#39;, grayim, delimiter = &#39;,&#39;, fmt = &#39;%.0f&#39;)

    predicted = classifier.predict(grayim)
    print(&#39;判定は、&#39; + str(predicted))

    plt.subplot(3, 5, 11)
    plt.axis(&#39;off&#39;)
    plt.imshow(img, cmap=plt.cm.gray_r, interpolation=&#39;nearest&#39;)
    plt.title(&#39;Original&#39;)
    plt.subplot(3, 5, 12)
    plt.axis(&#39;off&#39;)
    plt.imshow(im, cmap=plt.cm.gray_r, interpolation=&#39;nearest&#39;)
    plt.title(&#39;Prodicted %i&#39; % predicted)
    plt.show()

    if sys.version_info.major != 2:
        y_or_n = input(&#39;正しいですか？(y or n)&#39;)
    else:
        y_or_n = raw_input(&#39;正しいですか？(y or n)&#39;)

    if y_or_n == &#39;n&#39;:
        correct_digit = input(&#39;正しい数字を教えてください：&#39;)

        grayim = np.append(grayim, int(correct_digit))
        grayim = grayim.reshape(1, -1)

        f = open(join(module_path, &#39;data&#39;, &#39;digits.csv&#39;), &#39;a&#39;)
        np.savetxt(f, grayim, delimiter = &#39;,&#39;, fmt = &#39;%.0f&#39;)
        f.close()
        sleep(0.5)
    else:
        if sys.version_info.major != 2:
            next_y_or_n = input(&#39;続けますか？(y or n)&#39;)
        else:
            next_y_or_n = raw_input(&#39;続けますか？(y or n)&#39;)

        if next_y_or_n == &#39;n&#39;:
            break

&lt;/pre&gt;&quot;digits.csv&quot;には8x8のサイズで0～9の数字の画像データを、0～16の階調で格納し、最後にその画像が&lt;br /&gt;
示す数字の正解ラベルが付加されている。&lt;br /&gt;
&amp;nbsp;1行に64個（8x8）の値と、1個の正解ラベルで、65個の値を持ち、全部で1796行になる。&lt;br /&gt;
「scikit-learn 手書き 数字」等で検索すると、1796のデータを学習用と分類用に分けて、その結果を&lt;br /&gt;
&amp;nbsp;示すサンプルが多く見受けられる。&lt;br /&gt;
このスクリプトでは、&quot;digits.csv&quot;のデータをすべて読み込んでサポートベクトルマシンによる分類器を&lt;br /&gt;
用意し、同じディレクトリ内の画像データ&quot;digit_test.png&quot;を読み込んで分類器を使った判定を行う。&lt;br /&gt;
&lt;br /&gt;
画像&quot;digit_test.png&quot;は8x8ピクセルである必要はなく、例えば100x100でも良いし、80x100とかでも&lt;br /&gt;
8x8へ変換するようになっている。&lt;br /&gt;
&lt;br /&gt;
スクリプトを実行させると、10個の凡例と手書き画像のオリジナル・8x8変換後の判定が表示される。&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHoAf0CHYSXl0USeEm4rRv1eMVFjoqhBTcn5SEbPcdl97uICi9TWZ0M07HwxcqnO12-HkHEuvPdFerWd8CBthWsmXPxGMtDBsS5tg5dXbjQwM6bObhwpTFI930GzEU4nhrLTfiPcipPQFf/s1600/2018-08-05--1533414594_1280x1024_scrot.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;558&quot; data-original-width=&quot;648&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHoAf0CHYSXl0USeEm4rRv1eMVFjoqhBTcn5SEbPcdl97uICi9TWZ0M07HwxcqnO12-HkHEuvPdFerWd8CBthWsmXPxGMtDBsS5tg5dXbjQwM6bObhwpTFI930GzEU4nhrLTfiPcipPQFf/s1600/2018-08-05--1533414594_1280x1024_scrot.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;/div&gt;&lt;br /&gt;
一旦その表示ウィンドウを閉じると、「正しいですか？」と聞いてくるので答えを入力する。&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdb2OQhL3Yupr9Isx1dSeXSgn3mo20uFE4GA-Wm6ssx-iB8MQUCZPA-nGOvNuJFNE6P8cxL30wsPRpyyKQZLduaS3yNYUZ0tQ24nKzi9B7H-hy-F3v-NgP8SZIT8P6rwcQJg29pJzHp2uo/s1600/2018-08-05--1533414783_1280x1024_scrot.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;592&quot; data-original-width=&quot;900&quot; height=&quot;420&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdb2OQhL3Yupr9Isx1dSeXSgn3mo20uFE4GA-Wm6ssx-iB8MQUCZPA-nGOvNuJFNE6P8cxL30wsPRpyyKQZLduaS3yNYUZ0tQ24nKzi9B7H-hy-F3v-NgP8SZIT8P6rwcQJg29pJzHp2uo/s640/2018-08-05--1533414783_1280x1024_scrot.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;/div&gt;&lt;br /&gt;
「n」を入力すると、「正しい数字を教えてください」と聞いてくるので正解を入力する。&lt;br /&gt;
読み込んだデータに正解ラベルを付加した状態でデータに追加し、再度分類器を生成して判定を やり直す。&lt;br /&gt;
一度で駄目でも、何回か繰り返せば正解の判定を導き出すようになる。&lt;br /&gt;
「続けますか？」に答える前に、次に判定したい画像を&quot;digit_test.png&quot;として用意しておけば、&lt;br /&gt;
新たな画像を判定する。でないと、同じ画像の判定を繰り返すだけになるので注意。&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&lt;span style=&quot;color: blue;&quot;&gt;&lt;b&gt;ただ重要なのは、数字を理解して判定している訳ではなく、64個の値の組み合わせに正解を&lt;br /&gt;
紐付けているだけだと言うこと。&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: blue;&quot;&gt;&lt;b&gt;だから、アラビア数字じゃなく漢数字の画像データでも良いはず！&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
漢数字の画像を用意して、データの追加を何回か繰り替えして行けば、漢数字での判定が出きるようになる。&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&lt;span style=&quot;color: red;&quot;&gt;（要は、正解ラベルで意味づけをしているのは人間なので、数字である必要も、画像データである必要も無い）&lt;/span&gt;  &lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;おまけ（漢数字用データ）&lt;/b&gt; &lt;br /&gt;
&lt;pre class=&quot;prettyprint linenums&quot;&gt;0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,6,6,6,6,8,8,0,3,4,4,4,4,2,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,6,6,6,6,8,8,0,3,4,4,4,4,2,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,10,10,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,0,0,5,10,10,11,9,8,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,10,10,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,0,0,5,10,10,11,9,8,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2
0,0,0,0,0,0,0,0,0,0,9,11,10,8,0,0,0,0,0,0,0,0,0,0,0,0,2,9,9,0,0,0,0,0,0,1,0,0,0,0,2,4,5,6,9,11,9,1,3,6,6,4,1,0,4,5,0,0,0,0,0,0,0,0,3
0,0,0,0,0,0,0,0,0,0,9,11,10,8,0,0,0,0,0,0,0,0,0,0,0,0,2,9,9,0,0,0,0,0,0,1,0,0,0,0,2,4,5,6,9,11,9,1,3,6,6,4,1,0,4,5,0,0,0,0,0,0,0,0,3
0,0,0,0,0,0,0,0,1,1,3,5,6,8,1,0,9,6,10,9,11,8,4,0,4,7,6,5,10,6,4,0,2,12,11,0,9,13,2,0,2,9,4,4,6,12,3,0,0,3,6,6,5,6,2,0,0,0,0,0,0,0,0,0,4
0,0,0,0,0,0,0,0,1,1,3,5,6,8,1,0,9,6,10,9,11,8,4,0,4,7,6,5,10,6,4,0,2,12,11,0,9,13,2,0,2,9,4,4,6,12,3,0,0,3,6,6,5,6,2,0,0,0,0,0,0,0,0,0,4
0,0,0,0,0,0,0,0,0,3,10,10,10,8,0,0,0,0,0,10,2,0,0,0,0,3,7,13,6,4,0,0,0,1,7,9,4,10,0,0,0,0,7,4,4,7,0,0,7,10,12,10,12,11,11,10,0,0,0,0,0,0,0,0,5
0,0,0,0,0,0,0,0,0,3,10,10,10,8,0,0,0,0,0,10,2,0,0,0,0,3,7,13,6,4,0,0,0,1,7,9,4,10,0,0,0,0,7,4,4,7,0,0,7,10,12,10,12,11,11,10,0,0,0,0,0,0,0,0,5
0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,0,2,0,10,4,5,6,1,0,9,10,10,8,6,5,1,0,0,3,0,1,6,0,0,0,2,10,0,0,10,8,0,0,11,2,0,0,0,6,5,0,1,0,0,0,0,0,0,6
0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,0,2,0,10,4,5,6,1,0,9,10,10,8,6,5,1,0,0,3,0,1,6,0,0,0,2,10,0,0,10,8,0,0,11,2,0,0,0,6,5,0,1,0,0,0,0,0,0,6
0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,10,0,0,1,0,0,2,8,13,10,11,10,3,0,0,2,11,1,0,0,0,0,0,0,11,0,0,0,0,0,0,0,7,11,10,10,7,0,0,0,0,0,0,0,0,0,7
0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,10,0,0,1,0,0,2,8,13,10,11,10,3,0,0,2,11,1,0,0,0,0,0,0,11,0,0,0,0,0,0,0,7,11,10,10,7,0,0,0,0,0,0,0,0,0,7
0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,0,7,0,11,0,0,0,0,4,7,0,6,5,0,0,0,10,2,0,1,11,0,0,3,9,0,0,0,8,5,0,1,1,0,0,0,1,11,2,0,0,0,0,0,0,0,0,8
0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,0,7,0,11,0,0,0,0,4,7,0,6,5,0,0,0,10,2,0,1,11,0,0,3,9,0,0,0,8,5,0,1,1,0,0,0,1,11,2,0,0,0,0,0,0,0,0,8
0,0,0,5,0,0,0,0,0,0,0,11,0,0,0,0,0,2,8,13,12,10,0,0,0,0,8,6,7,4,0,0,0,0,11,0,8,2,0,0,0,2,10,0,6,7,0,7,0,8,4,0,0,9,11,7,0,1,0,0,0,0,0,0,9
0,0,0,5,0,0,0,0,0,0,0,11,0,0,0,0,0,2,8,13,12,10,0,0,0,0,8,6,7,4,0,0,0,0,11,0,8,2,0,0,0,2,10,0,6,7,0,7,0,8,4,0,0,9,11,7,0,1,0,0,0,0,0,0,9

&lt;/pre&gt;&lt;br /&gt;
&lt;b&gt;MLPClassifier使用版&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;span style=&quot;color: red;&quot;&gt;※追記1（2018/08/14　16:20）※&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
Python2にも対応したつもり&lt;br /&gt;
&lt;b&gt;&lt;span style=&quot;color: red;&quot;&gt;※追記2（2018/08/14　19:40）※&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
バグ取り&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-py linenums&quot;&gt;#!/usr/bin/env python
# -*- coding: utf-8 -*-

import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.neural_network import MLPClassifier

import numpy as np
import cv2
from time import sleep
from os.path import dirname, join
from sklearn.datasets.base import Bunch
import sys

y_or_n = &#39;n&#39;
module_path = dirname(__file__)

def load_digits():
    module_path = dirname(__file__)
    data = np.loadtxt(join(module_path, &#39;data&#39;, &#39;digits.csv&#39;),
                      delimiter=&#39;,&#39;)

    target = data[:, -1].astype(np.int)
    flat_data = data[:, :-1]
    images = flat_data.view()
    images.shape = (-1, 8, 8)

    return Bunch(data=flat_data,
                 target=target,
                 target_names=np.arange(10),
                 images=images)


while(True):
    if y_or_n == &#39;n&#39;:
        digits = load_digits()
        n_samples = len(digits.images)
        data = digits.images.reshape((n_samples, -1))

        classifier = MLPClassifier(hidden_layer_sizes=(100, 100, 100, 10), max_iter=10000, tol=0.00001, random_state=1)
        print(classifier)
        classifier.fit(data, digits.target)

    images_and_labels = list(zip(digits.images, digits.target))
    for index, (image, label) in enumerate(images_and_labels[:10]):
        plt.subplot(3, 5, index + 1)
        plt.axis(&#39;off&#39;)
        plt.imshow(image, cmap=plt.cm.gray_r, interpolation=&#39;nearest&#39;)
        plt.title(&#39;Training %i&#39; % label)

    img = cv2.imread(&#39;digit_test.png&#39;)

    size = (8, 8)
    im = cv2.resize(img, size, interpolation=cv2.INTER_AREA)

    imgray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
    #print(imgray)
    grayim = np.round((255 - imgray) / 16)
    grayim = grayim.reshape(1, -1)
    print(grayim)
    np.savetxt(&#39;digit_test.csv&#39;, grayim, delimiter = &#39;,&#39;, fmt = &#39;%.0f&#39;)

    predicted = classifier.predict(grayim)
    print(&#39;判定は、&#39; + str(predicted))

    plt.subplot(3, 5, 11)
    plt.axis(&#39;off&#39;)
    plt.imshow(img, cmap=plt.cm.gray_r, interpolation=&#39;nearest&#39;)
    plt.title(&#39;Original&#39;)
    plt.subplot(3, 5, 12)
    plt.axis(&#39;off&#39;)
    plt.imshow(im, cmap=plt.cm.gray_r, interpolation=&#39;nearest&#39;)
    plt.title(&#39;Prodicted %i&#39; % predicted)
    plt.show()

    if sys.version_info.major != 2:
        y_or_n = input(&#39;正しいですか？(y or n)&#39;)
    else:
        y_or_n = raw_input(&#39;正しいですか？(y or n)&#39;)

    if y_or_n == &#39;n&#39;:
        correct_digit = input(&#39;正しい数字を教えてください：&#39;)

        grayim = np.append(grayim, int(correct_digit))
        #print(grayim)
        grayim = grayim.reshape(1, -1)

        f = open(join(module_path, &#39;data&#39;, &#39;digits.csv&#39;), &#39;a&#39;)
        np.savetxt(f, grayim, delimiter = &#39;,&#39;, fmt = &#39;%.0f&#39;)
        f.close()
        sleep(1)
    else:
        if sys.version_info.major != 2:
            next_y_or_n = input(&#39;続けますか？(y or n)&#39;)
        else:
            next_y_or_n = raw_input(&#39;続けますか？(y or n)&#39;)

        if next_y_or_n == &#39;n&#39;:
            break

&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://aoo10yan.blogspot.com/feeds/2210356041109501188/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://aoo10yan.blogspot.com/2018/08/scikit-learn.html#comment-form' title='1 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7359781935835547652/posts/default/2210356041109501188'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7359781935835547652/posts/default/2210356041109501188'/><link rel='alternate' type='text/html' href='http://aoo10yan.blogspot.com/2018/08/scikit-learn.html' title='scikit-learnで漢数字認識'/><author><name>AO_o10yan</name><uri>http://www.blogger.com/profile/00449541977510719198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3SJ_vlXghphmsLUqqQQZmZvMxNZM48lVvgyuR-QyEjoxK-9l70UQVs7J9IdSasbq6CTAaioxIdA4X8ggB_FzFx7BecCxgvawWrsunoMqUkIgLHMz4l5eB5r1B0EiFqULw32rIg14spD51/s72-c/2018-08-04--1533349935_1280x1024_scrot.png" height="72" width="72"/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7359781935835547652.post-563225609410452330</id><published>2018-05-03T09:04:00.000+09:00</published><updated>2018-05-03T09:04:44.587+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="raspberry pi"/><category scheme="http://www.blogger.com/atom/ns#" term="robot"/><category scheme="http://www.blogger.com/atom/ns#" term="servoblaster"/><title type='text'>ServoBlaster が更新されました</title><content type='html'>&lt;a href=&quot;http://aoo10yan.blogspot.jp/2017/03/raspberry-pi-kernel-49servoblaster.html&quot; target=&quot;_blank&quot;&gt;去年こちらに書いた&lt;/a&gt;ServoBlasterの問題が修正されていました。&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;https://github.com/richardghirst/PiBits/tree/master/ServoBlaster&quot; target=&quot;_blank&quot;&gt;&amp;nbsp;https://github.com/richardghirst/PiBits/tree/master/ServoBlaster&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
kernel 4.9以降に&quot;/proc/cpuinfo&quot;の&quot;Hardware&quot;情報を元に&quot;board_model&quot;を判定する方法&lt;br /&gt;
（実際は、&quot;board_model&quot;からgpioのベースになるアドレスを設定する方法）に不具合が&lt;br /&gt;
出ていましたが、&lt;a href=&quot;https://www.raspberrypi.org/documentation/hardware/raspberrypi/peripheral_addresses.md&quot; target=&quot;_blank&quot;&gt;こちらの&quot;&lt;code&gt;bcm_host_get_peripheral_address()&lt;/code&gt;&quot; &lt;/a&gt;を使う方法になっています。&lt;br /&gt;
&lt;br /&gt;
手持ちのRespberry Pi 2 Model Bでの動作確認ができました。 &lt;br /&gt;
</content><link rel='replies' type='application/atom+xml' href='http://aoo10yan.blogspot.com/feeds/563225609410452330/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://aoo10yan.blogspot.com/2018/05/servoblaster.html#comment-form' title='1 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7359781935835547652/posts/default/563225609410452330'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7359781935835547652/posts/default/563225609410452330'/><link rel='alternate' type='text/html' href='http://aoo10yan.blogspot.com/2018/05/servoblaster.html' title='ServoBlaster が更新されました'/><author><name>AO_o10yan</name><uri>http://www.blogger.com/profile/00449541977510719198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7359781935835547652.post-8708130607220016294</id><published>2018-02-17T14:20:00.002+09:00</published><updated>2018-02-17T14:20:18.633+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="linux"/><category scheme="http://www.blogger.com/atom/ns#" term="opencv"/><title type='text'>OpenCVで遊ぶ</title><content type='html'>OpenCVのテンプレートマッチングを少し試していて思いついた。&lt;br /&gt;
テンプレートの検出画面をターゲティングモニタ風にしてみた。&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;iframe width=&quot;320&quot; height=&quot;266&quot; class=&quot;YOUTUBE-iframe-video&quot; data-thumbnail-src=&quot;https://i.ytimg.com/vi/3yuTdxiOcwg/0.jpg&quot; src=&quot;https://www.youtube.com/embed/3yuTdxiOcwg?feature=player_embedded&quot; frameborder=&quot;0&quot; allowfullscreen&gt;&lt;/iframe&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://aoo10yan.blogspot.com/feeds/8708130607220016294/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://aoo10yan.blogspot.com/2018/02/opencv_17.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7359781935835547652/posts/default/8708130607220016294'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7359781935835547652/posts/default/8708130607220016294'/><link rel='alternate' type='text/html' href='http://aoo10yan.blogspot.com/2018/02/opencv_17.html' title='OpenCVで遊ぶ'/><author><name>AO_o10yan</name><uri>http://www.blogger.com/profile/00449541977510719198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img.youtube.com/vi/3yuTdxiOcwg/default.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7359781935835547652.post-4686318945083052805</id><published>2018-02-11T21:17:00.000+09:00</published><updated>2020-03-10T09:05:12.948+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="linux"/><category scheme="http://www.blogger.com/atom/ns#" term="opencv"/><category scheme="http://www.blogger.com/atom/ns#" term="raspberry pi"/><title type='text'>動画でOpenCV(テンプレートマッチング)</title><content type='html'>WebカメラLogicool c270を買ったので &lt;a href=&quot;http://aoo10yan.blogspot.jp/2018/01/opencv.html&quot; target=&quot;_blank&quot;&gt;「OpenCVのテンプレートマッチングを試す 」&lt;/a&gt;を&lt;br /&gt;
動画でやってみた。&lt;br /&gt;
&lt;br /&gt;
今回は、OpenCVのチュートリアル&lt;a href=&quot;http://labs.eecs.tottori-u.ac.jp/sd/Member/oyamada/OpenCV/html/py_tutorials/py_gui/py_video_display/py_video_display.html&quot; target=&quot;_blank&quot;&gt;「動画を扱う」&lt;/a&gt;を参考にした。 &lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;iframe allowfullscreen=&quot;&quot; class=&quot;YOUTUBE-iframe-video&quot; data-thumbnail-src=&quot;https://i.ytimg.com/vi/GYxaMp-W2_A/0.jpg&quot; frameborder=&quot;0&quot; height=&quot;266&quot; src=&quot;https://www.youtube.com/embed/GYxaMp-W2_A?feature=player_embedded&quot; width=&quot;320&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;iframe allowfullscreen=&quot;&quot; class=&quot;YOUTUBE-iframe-video&quot; data-thumbnail-src=&quot;https://i.ytimg.com/vi/xbvQ2Z2OeRU/0.jpg&quot; frameborder=&quot;0&quot; height=&quot;266&quot; src=&quot;https://www.youtube.com/embed/xbvQ2Z2OeRU?feature=player_embedded&quot; width=&quot;320&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;iframe allowfullscreen=&quot;&quot; class=&quot;YOUTUBE-iframe-video&quot; data-thumbnail-src=&quot;https://i.ytimg.com/vi/olLzLlAj1Tc/0.jpg&quot; frameborder=&quot;0&quot; height=&quot;266&quot; src=&quot;https://www.youtube.com/embed/olLzLlAj1Tc?feature=player_embedded&quot; width=&quot;320&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;br /&gt;
テンプレート画像として、&quot;temp100.png&quot;　&quot;temp200.png&quot;　&quot;temp300.png&quot;を用意。&lt;br /&gt;
Logicool c270から読み込んだ画像を処理する。&lt;br /&gt;
Raspberry Pi 2 Model Bの処理を考えて、サイズを320x240、フレームレート15を設定。&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;color: red;&quot;&gt;&lt;b&gt;※注意※&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: red;&quot;&gt;自分の環境では1回目の実行は問題ないが、2回目の実行で&quot;cap = cv2.VideoCapture(0)&quot;が&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: red;&quot;&gt;正常に行われないようなので、&quot;cap.get(cv2.CAP_PROP_FPS) == 0&quot;で判定しながら&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: red;&quot;&gt;繰り返し処理を入れてあります。&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-py linenums&quot;&gt;#!/usr/bin/env python
# -*- coding: utf-8 -*-

import cv2
import numpy as np
import tkinter

cap = cv2.VideoCapture(0)

while(cap.get(cv2.CAP_PROP_FPS) == 0):
    cap.release()
    cap = cv2.VideoCapture(0)

cap.set(3, 320)
cap.set(4, 240)
cap.set(5, 15.0)

print(cap.get(3))
print(cap.get(4))
print(cap.get(5))

grid_x = (25, 115, 205, 295)
grid_y = (45, 95, 145, 195)

fourcc = cv2.VideoWriter_fourcc(*&quot;XVID&quot;)
out = cv2.VideoWriter(&#39;output.avi&#39;, fourcc, 15.0, (320,240))

while(True):
    res_100 = &quot;???&quot;
    res_200 = &quot;???&quot;
    res_300 = &quot;???&quot;
    text =&quot;???&quot;

    # Capture frame-by-frame
    ret, frame = cap.read()
    
    img = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    for temp_num in [100, 200, 300]:
        temp = cv2.imread(&quot;temp&quot; + str(temp_num) + &quot;.png&quot;, 0)
        result = cv2.matchTemplate(img, temp, cv2.TM_CCOEFF_NORMED)
        min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)

        if max_val &amp;gt; 0.8:
            b = 0
            g = 0
            r = 0
        
            if temp_num == 100:
                b = 255
            if temp_num == 200:
                g = 255
            if temp_num == 300:
                r = 255

            top_left = max_loc
            w, h = temp.shape[::-1]
            bottom_right = (top_left[0] + w, top_left[1] + h)

            res_x = []
            res_y = []

            for i in [0, 1, 2]:
                if top_left[0] &amp;gt;= grid_x[i] and top_left[0] &amp;lt; grid_x[i + 1]:
                    if (i + 1 in res_x) == False:
                        res_x.append(i + 1)
                    for n in [0, 1, 2]:
                        if top_left[1] &amp;gt;= grid_y[n] and top_left[1] &amp;lt; grid_y[n + 1]:
                            if (n + 1 in res_y) == False:
                                res_y.append(n + 1)

                                #print(&quot;temp&quot; + str(temp_num) + &quot;.png = &quot; + str(res_x[0]) + &quot;-&quot; + str(res_y[0]))

                                if temp_num == 100:
                                    res_100 = str(res_x[0]) + &quot;-&quot; + str(res_y[0])
                                if temp_num == 200:
                                    res_200 = str(res_x[0]) + &quot;-&quot; + str(res_y[0])
                                if temp_num == 300:
                                    res_300 = str(res_x[0]) + &quot;-&quot; + str(res_y[0])

                                text = str(res_x[0]) + &quot;-&quot; + str(res_y[0]) + &quot;(&quot; + str(&quot;{:.3}&quot;.format(max_val)) + &quot;)&quot;

            cv2.rectangle(frame, top_left, bottom_right, (b, g, r), 2)
            cv2.putText(frame, text, (top_left[0] - 5, top_left[1] - 5), cv2.FONT_HERSHEY_PLAIN, 0.8, (b, g, r), 1, cv2.LINE_AA)

    # Display the resulting frame
    # write the frame
    out.write(frame)

    cv2.imshow(&quot;frame&quot;, frame)

    key = cv2.waitKey(1)&amp;amp;0xff
    if key == ord(&quot;s&quot;):

        label = tkinter.Label(None, text = &quot;1 = &quot; + res_100 + &quot;\n2 = &quot; + res_200 + &quot;\n3 = &quot; + res_300, font=(&quot;Times&quot;, &quot;28&quot;))
        label.pack()
        label.mainloop()

        cv2.imwrite(&quot;capture.png&quot;, frame)
        #break

    if key == ord(&quot;q&quot;):
        break

# When everything done, release the capture
cap.release()
out.release()
cv2.destroyAllWindows()

&lt;/pre&gt;&lt;br /&gt;
上のコードでは、&quot;s&quot;キーが押された時に&quot;tkinter&quot;を使って検出対象の位置情報を表示させているが、&lt;br /&gt;
これは一例なので、検出結果から「ここで何かする」って意味になる。&lt;br /&gt;
更に別スレッド、別プロセスにすれば動画（画像）の取得を止めること無く「何かする」&lt;br /&gt;
が実行出きるので、実際の運用はそう言った使い方になる筈。 </content><link rel='replies' type='application/atom+xml' href='http://aoo10yan.blogspot.com/feeds/4686318945083052805/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://aoo10yan.blogspot.com/2018/02/opencv.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7359781935835547652/posts/default/4686318945083052805'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7359781935835547652/posts/default/4686318945083052805'/><link rel='alternate' type='text/html' href='http://aoo10yan.blogspot.com/2018/02/opencv.html' title='動画でOpenCV(テンプレートマッチング)'/><author><name>AO_o10yan</name><uri>http://www.blogger.com/profile/00449541977510719198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img.youtube.com/vi/GYxaMp-W2_A/default.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7359781935835547652.post-7994716140795106559</id><published>2018-01-04T14:34:00.001+09:00</published><updated>2020-03-07T15:41:30.713+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="arch"/><category scheme="http://www.blogger.com/atom/ns#" term="linux"/><category scheme="http://www.blogger.com/atom/ns#" term="opencv"/><category scheme="http://www.blogger.com/atom/ns#" term="raspberry pi"/><title type='text'>OpenCVのテンプレートマッチングを試す</title><content type='html'>&lt;span id=&quot;goog_350103965&quot;&gt;&lt;/span&gt;&lt;span id=&quot;goog_350103966&quot;&gt;&lt;/span&gt;以前にOpenCVを使って顔検出をやってみたが、今回はテンプレートマッチングで、&lt;br /&gt;
簡易的に数字を検出してみる。&lt;br /&gt;
&amp;nbsp;&lt;span style=&quot;color: blue;&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: blue;&quot;&gt;&lt;b&gt;下のページを参考にさせてもらいました。有り難うございました。&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;a href=&quot;http://www.tech-tech.xyz/archives/3065942.html&quot;&gt;http://www.tech-tech.xyz/archives/3065942.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
本当は画像の中から文字を検出したかったのだが、意外と面倒そうだった。&lt;br /&gt;
手書きの文字やフォント不明の文字を認識したいわけではなく、予め用意した数字と&lt;br /&gt;
同じものさえ検出できればよかったので、テンプレート画像との一致を見つけることで&lt;br /&gt;
良しとした。&lt;br /&gt;
&lt;br /&gt;
先ず、テンプレート画像を用意する。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEju1-Ma-jyl-4vbW5l_jYOPgpLkL0w_v4SVN3jtlZmrL0F6ZtzGVTAIosQmVGZsRgUQBWgoAUPFjm73RALSvokymZ6XnRi7TDmkGrdcW_xlbSdq9o2AWQSiJnFPryRev1HmT6d53x5KfjNK/s1600/test0.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;235&quot; data-original-width=&quot;379&quot; height=&quot;198&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEju1-Ma-jyl-4vbW5l_jYOPgpLkL0w_v4SVN3jtlZmrL0F6ZtzGVTAIosQmVGZsRgUQBWgoAUPFjm73RALSvokymZ6XnRi7TDmkGrdcW_xlbSdq9o2AWQSiJnFPryRev1HmT6d53x5KfjNK/s320/test0.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
上の画像から、検出したい数字の部分を切り取ってテンプレート画像を作る。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8xAythP-t79BXBd2UYfCaSjmMAv_JRumWfVgeJ5uzfMvtxufz0Dy267qcAVDr39rLV_Qj246PHUK8jHBeJJ0xNQC5ruXAqhpqAOLSUdpmOhGkFE3fzrdP32PEih_0w00_HS3RcqIplL31/s1600/temp100.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;82&quot; data-original-width=&quot;63&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8xAythP-t79BXBd2UYfCaSjmMAv_JRumWfVgeJ5uzfMvtxufz0Dy267qcAVDr39rLV_Qj246PHUK8jHBeJJ0xNQC5ruXAqhpqAOLSUdpmOhGkFE3fzrdP32PEih_0w00_HS3RcqIplL31/s1600/temp100.png&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikOfkUlx7z9c7DHGqbjd1ZPeBbqR5o6ZTj9JAIUPzMUzdJstQHKNtlJ9h4G8JhsnsTMAexBF3JSyWM-5Wej1JRv25pNPwMrtWL0Wg3LpDw21uFWOT4aLRL4nHvtRoGjMT7o-XvKCWHzsGv/s1600/temp200.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;82&quot; data-original-width=&quot;82&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikOfkUlx7z9c7DHGqbjd1ZPeBbqR5o6ZTj9JAIUPzMUzdJstQHKNtlJ9h4G8JhsnsTMAexBF3JSyWM-5Wej1JRv25pNPwMrtWL0Wg3LpDw21uFWOT4aLRL4nHvtRoGjMT7o-XvKCWHzsGv/s1600/temp200.png&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0n5fQJnj5QvbscY8hjtEZ17m33ooiSNY1IsVjJbc9KiZbUgelFLQ97aCFtUtV4W4plN9Zp5UG8ScNXzLCwjTssOjJwwkL_jKp3iG5Z7WvfR_qFbh4EALZD1jqhsZLC7ah0Bi7lWHdr60O/s1600/temp300.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;82&quot; data-original-width=&quot;82&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0n5fQJnj5QvbscY8hjtEZ17m33ooiSNY1IsVjJbc9KiZbUgelFLQ97aCFtUtV4W4plN9Zp5UG8ScNXzLCwjTssOjJwwkL_jKp3iG5Z7WvfR_qFbh4EALZD1jqhsZLC7ah0Bi7lWHdr60O/s1600/temp300.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;これら「1」「2」「3」のテンプレートを使って検出を行う。&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-py linenums&quot;&gt;#!/usr/bin/env python
# -*- coding: utf-8 -*-

import cv2
import shutil

shutil.copyfile(&quot;test.jpg&quot;,&quot;result.jpg&quot;)

img = cv2.imread(&quot;result.jpg&quot;, 0)

for temp_num in [1, 2, 3]:
    temp = cv2.imread(&quot;temp&quot; + str(temp_num) + &quot;.png&quot;, 0)

    result = cv2.matchTemplate(img, temp, cv2.TM_CCOEFF_NORMED)

    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)

    if max_val &amp;gt; 0.8:
        top_left = max_loc
        w, h = temp.shape[::-1]
        bottom_right = (top_left[0] + w, top_left[1] + h)

        result = cv2.imread(&quot;result.jpg&quot;)
        cv2.rectangle(result,top_left, bottom_right, (255, 0, 0), 2)
        cv2.imwrite(&quot;result.jpg&quot;, result)
&lt;/pre&gt;&lt;br /&gt;
&lt;b&gt;&lt;span style=&quot;color: red;&quot;&gt;※追記1（2018/01/04　20:20）※&lt;/span&gt;&lt;/b&gt; &lt;br /&gt;
&amp;nbsp;　誤検出を減らすように、テンプレートマッチングの結果から&lt;br /&gt;
&quot;max_val&quot;（&lt;strike&gt;グレースケールで&lt;/strike&gt;最も高い&lt;strike&gt;輝度の&lt;/strike&gt;値）が0.8より大きい時だけ　&lt;br /&gt;
枠表示をするように変更しました。&lt;br /&gt;
何回か試したところ、正常に検出できた場合の&quot;max_val&quot;は、ほぼ0.9以上。&lt;br /&gt;
誤検出の場合は、0.7以下でした。&lt;br /&gt;
そこで「エイヤッ」と、0.8を設定しました。&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEipD6BjnM-7C9MS7xwkZ2_1AIHcl86VkXSXrXrZzn1N9siMlfI1qrTolY_EwiOevRAD5UWfD7GPIX5M7hzYYaRnd5oEGFEuHqOhcFApy7ZZRbiugmf4aDMHUQfth6ikcrbV1JSac8cmCPDV/s1600/result10.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;482&quot; data-original-width=&quot;777&quot; height=&quot;198&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEipD6BjnM-7C9MS7xwkZ2_1AIHcl86VkXSXrXrZzn1N9siMlfI1qrTolY_EwiOevRAD5UWfD7GPIX5M7hzYYaRnd5oEGFEuHqOhcFApy7ZZRbiugmf4aDMHUQfth6ikcrbV1JSac8cmCPDV/s320/result10.jpg&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
今回は検出する画像がjpg、テンプレート画像がpngという変則コードになってしまったが&lt;br /&gt;
実行できれば問題ない（本当かよ？）&lt;br /&gt;
&lt;br /&gt;
実際のカードを作って、それらを並べ替えてやってみた。&lt;br /&gt;
元画像を印刷した後、切り取って数字カードを作る。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPbTLtIS9ueKRJt6Y44V2MVw-zG8Yix4dQgxKlBDfQHRb52uB5YnwsPJjmYIMpt-wp4kUn3ILwXohECu27wqJ-AWXJaDhriIDuk0vx4aHWa5RzofJDFPD7YiIa52mOzpAmpnlE4eYHXPC0/s1600/pre0.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1200&quot; data-original-width=&quot;1600&quot; height=&quot;240&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPbTLtIS9ueKRJt6Y44V2MVw-zG8Yix4dQgxKlBDfQHRb52uB5YnwsPJjmYIMpt-wp4kUn3ILwXohECu27wqJ-AWXJaDhriIDuk0vx4aHWa5RzofJDFPD7YiIa52mOzpAmpnlE4eYHXPC0/s320/pre0.jpg&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
それらのカードを適当に並べ替えて検出してみた。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvCWTzn5-Pef5DUgkHJoccdTK4kspgH981-U82QxUKsOK_IqglyhMlbXEhm4c3SPE_XZA9dt0978Ac2tneI52GoJCL8mJv468G1HU9Xwy69yg9s2pM7TzuIQyjnMbuaWKCtkcqNLcS9SOL/s1600/pre3.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;960&quot; data-original-width=&quot;1280&quot; height=&quot;240&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvCWTzn5-Pef5DUgkHJoccdTK4kspgH981-U82QxUKsOK_IqglyhMlbXEhm4c3SPE_XZA9dt0978Ac2tneI52GoJCL8mJv468G1HU9Xwy69yg9s2pM7TzuIQyjnMbuaWKCtkcqNLcS9SOL/s320/pre3.jpg&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCbqzSIAvURanIq7BXF-uD7qG46adk8-F02kqbUQz1EfMiRzhVo_FWYylFai7_dhyphenhyphen8b_BmFUmWZ9zp6CNeLTO_NuxsLWS9-t6vNHHNTBW19EHr9UzpuZ39B6ap0KmRI0JHx8xrIwP26gTb/s1600/result300.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;960&quot; data-original-width=&quot;1280&quot; height=&quot;240&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCbqzSIAvURanIq7BXF-uD7qG46adk8-F02kqbUQz1EfMiRzhVo_FWYylFai7_dhyphenhyphen8b_BmFUmWZ9zp6CNeLTO_NuxsLWS9-t6vNHHNTBW19EHr9UzpuZ39B6ap0KmRI0JHx8xrIwP26gTb/s320/result300.jpg&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;更に、枠を外してやってみた。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjiqeJRcg61P4ZAavdlTM1ROpoeY40s40CT58v6N3tA5WAxLwYxjlqz0APtoy3rDGmGIRXWsNzRXDOJ0_WYn2b4vp8YYG6na3BhBCKVrOSxnGV0CiJw0j6mqsIHfzGfdbVuW1kx2oQMLNUG/s1600/pre4.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;960&quot; data-original-width=&quot;1280&quot; height=&quot;240&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjiqeJRcg61P4ZAavdlTM1ROpoeY40s40CT58v6N3tA5WAxLwYxjlqz0APtoy3rDGmGIRXWsNzRXDOJ0_WYn2b4vp8YYG6na3BhBCKVrOSxnGV0CiJw0j6mqsIHfzGfdbVuW1kx2oQMLNUG/s320/pre4.jpg&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhombLgWIAvTYm1sb3Y_gA-FFTgrwrS6T4a8LRm7n_er66lTSjhbaRbep9ZZ61cZDdteicOCtHg9wal3fXtMhvd35oBkn6rdDtoLphX52pSfb0AucCLJN4reW2Al8kyftRr4NtV1GBl2UZZ/s1600/result400.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;960&quot; data-original-width=&quot;1280&quot; height=&quot;240&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhombLgWIAvTYm1sb3Y_gA-FFTgrwrS6T4a8LRm7n_er66lTSjhbaRbep9ZZ61cZDdteicOCtHg9wal3fXtMhvd35oBkn6rdDtoLphX52pSfb0AucCLJN4reW2Al8kyftRr4NtV1GBl2UZZ/s320/result400.jpg&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
＜結果＞&lt;br /&gt;
・影があったり、余分な物が写っている画像でも、正常に検出ができた。&lt;br /&gt;
&lt;br /&gt;
＜問題点＞&lt;br /&gt;
・検出する画像の数字部分とテンプレート画像のサイズが（大体）合っていないと、&lt;br /&gt;
以下のようになる。&lt;br /&gt;
&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgoZL2VPvtkdg91AaDKdfBdCfS9gMlM5QakEpOz4MihEXx8lYGW8_wfqqI2CGYF41_2cezcJnFUf_vAmjIHQBW2Bmz6BVrJoouIrheKs_8olaSDSGalZt4rkM2PsvR2fMOns_xI0B5ClZZj/s1600/result01.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;960&quot; data-original-width=&quot;1280&quot; height=&quot;240&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgoZL2VPvtkdg91AaDKdfBdCfS9gMlM5QakEpOz4MihEXx8lYGW8_wfqqI2CGYF41_2cezcJnFUf_vAmjIHQBW2Bmz6BVrJoouIrheKs_8olaSDSGalZt4rkM2PsvR2fMOns_xI0B5ClZZj/s320/result01.jpg&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;間違った検出。画像の数字に対してテンプレートが小さい&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&amp;nbsp;・検出する画像が大きいと時間が掛かる。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
</content><link rel='replies' type='application/atom+xml' href='http://aoo10yan.blogspot.com/feeds/7994716140795106559/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://aoo10yan.blogspot.com/2018/01/opencv.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7359781935835547652/posts/default/7994716140795106559'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7359781935835547652/posts/default/7994716140795106559'/><link rel='alternate' type='text/html' href='http://aoo10yan.blogspot.com/2018/01/opencv.html' title='OpenCVのテンプレートマッチングを試す'/><author><name>AO_o10yan</name><uri>http://www.blogger.com/profile/00449541977510719198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEju1-Ma-jyl-4vbW5l_jYOPgpLkL0w_v4SVN3jtlZmrL0F6ZtzGVTAIosQmVGZsRgUQBWgoAUPFjm73RALSvokymZ6XnRi7TDmkGrdcW_xlbSdq9o2AWQSiJnFPryRev1HmT6d53x5KfjNK/s72-c/test0.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7359781935835547652.post-459277629702121240</id><published>2017-10-15T11:30:00.000+09:00</published><updated>2017-10-15T11:30:15.896+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="raspberry pi"/><category scheme="http://www.blogger.com/atom/ns#" term="scratch"/><title type='text'>Scratch で日本語入力</title><content type='html'>Twitter上で「Scratchでキーボード入力から変数の値を変えるには？」的なつぶやきを見た。&lt;br /&gt;
&lt;span style=&quot;background-color: white; font-size: 16px; white-space: pre-wrap;&quot;&gt;「○○と聞いて待つ」を使うんじゃ面白くないから、&lt;/span&gt;&lt;span style=&quot;background-color: white; font-size: 16px; white-space: pre-wrap;&quot;&gt;「○○キーが押されたとき」を&lt;/span&gt;&lt;span style=&quot;background-color: white; font-size: 16px; white-space: pre-wrap;&quot;&gt;使う方法を&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white; font-size: 16px; white-space: pre-wrap;&quot;&gt;考えていたら、ローマ字漢字変換みたいなものになった。&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white; font-size: 16px; white-space: pre-wrap;&quot;&gt;
&lt;/span&gt; &lt;span style=&quot;background-color: white; white-space: pre-wrap;&quot;&gt;&lt;a href=&quot;https://scratch.mit.edu/projects/175719052/&quot; target=&quot;_blank&quot;&gt;https://scratch.mit.edu/projects/175719052/&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTTWjz3GJYC-B-pq8qKkArLGPqLzOEOHa4gGoSfFo6auEDfXtR6-GBaHKHZKm014Tp6-wh5x6UJUuvXXX80-4auRXJXnQSN013I9KtDmnxYQKfYWh2RH76koNqa1GTuKIOgUXz5IrzUh38/s1600/2017-10-09--1507518825_513x505_scrot.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;505&quot; data-original-width=&quot;513&quot; height=&quot;393&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTTWjz3GJYC-B-pq8qKkArLGPqLzOEOHa4gGoSfFo6auEDfXtR6-GBaHKHZKm014Tp6-wh5x6UJUuvXXX80-4auRXJXnQSN013I9KtDmnxYQKfYWh2RH76koNqa1GTuKIOgUXz5IrzUh38/s400/2017-10-09--1507518825_513x505_scrot.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
リストに、変換する候補の漢字を保持しており、そのリストに対してインクリメンタルサーチ&lt;br /&gt;
っぽい動きをで候補を絞り込む。&lt;br /&gt;
要は、ひらがな（読み）の文字が増える毎に検索を繰り返しているだけなので、『予測』&lt;br /&gt;
などの高級な事は何一つやっていない。&lt;br /&gt;
&lt;br /&gt;
それと、リスト名を変数で指定する方法が分からなかったので、複数のリストに対して&lt;br /&gt;
同様の処理をするスクリプトを大量に用意してる。この辺はスマートな方法があるはず。&lt;br /&gt;
&lt;br /&gt;
契機となっTwitterのつぶやきと、「かな入力」の刺激を与えてくれた&lt;a href=&quot;https://scratch.mit.edu/projects/172241524/&quot; target=&quot;_blank&quot;&gt;dream1030さんの&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;https://scratch.mit.edu/projects/172241524/&quot; target=&quot;_blank&quot;&gt;作品「日本語＆数字入力機」&lt;/a&gt;に感謝。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://aoo10yan.blogspot.com/feeds/459277629702121240/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://aoo10yan.blogspot.com/2017/10/scratch.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7359781935835547652/posts/default/459277629702121240'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7359781935835547652/posts/default/459277629702121240'/><link rel='alternate' type='text/html' href='http://aoo10yan.blogspot.com/2017/10/scratch.html' title='Scratch で日本語入力'/><author><name>AO_o10yan</name><uri>http://www.blogger.com/profile/00449541977510719198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTTWjz3GJYC-B-pq8qKkArLGPqLzOEOHa4gGoSfFo6auEDfXtR6-GBaHKHZKm014Tp6-wh5x6UJUuvXXX80-4auRXJXnQSN013I9KtDmnxYQKfYWh2RH76koNqa1GTuKIOgUXz5IrzUh38/s72-c/2017-10-09--1507518825_513x505_scrot.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7359781935835547652.post-3191820430196596012</id><published>2017-09-10T14:38:00.000+09:00</published><updated>2017-09-14T22:28:20.498+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="linux"/><category scheme="http://www.blogger.com/atom/ns#" term="raspberry pi"/><title type='text'>Raspbian Stretchの迷走（？）</title><content type='html'>&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjpFNuBkxjeQiMNUr1GgjBRtfaKJjnlQopXTl0HZ7cHqa17QJLOs_s8upEyFPChsjpMeNPIgCqjzmzr3dVRiSvu7iGNreoqWrhxdBzh0_wm17Fi6OXsHrPhZ3QrqUb61U0HTPpDj2WKIEH/s1600/2017-09-10--1505021690_1024x768_scrot.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;768&quot; data-original-width=&quot;1024&quot; height=&quot;480&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjpFNuBkxjeQiMNUr1GgjBRtfaKJjnlQopXTl0HZ7cHqa17QJLOs_s8upEyFPChsjpMeNPIgCqjzmzr3dVRiSvu7iGNreoqWrhxdBzh0_wm17Fi6OXsHrPhZ3QrqUb61U0HTPpDj2WKIEH/s640/2017-09-10--1505021690_1024x768_scrot.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
2017-09-07-raspbian-stretchでネットワークインターフェースの命名規則が変わった。&lt;br /&gt;
というか、「元に戻った」。&lt;br /&gt;
&lt;a href=&quot;http://downloads.raspberrypi.org/raspbian/release_notes.txt&quot; target=&quot;_blank&quot;&gt;http://downloads.raspberrypi.org/raspbian/release_notes.txt&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Raspbian jessieまでのバージョンでは、ネットワークインターフェースには、&lt;br /&gt;
eth0、eth1（無線なら、wlan0、wlan1）等の名前が付けられていた。&lt;br /&gt;
それが、Stretchからは、インターフェース機器のMACアドレスを基に生成する&lt;br /&gt;
enx??????????、wlx??????????（&quot;??????????&quot;はMACアドレス）と言う形式になった。&lt;br /&gt;
&amp;nbsp;これまでの、eth0、eth1などの番号は、kernelがネットワークインターフェースを&lt;br /&gt;
読み込む順番で振られている為、読み込みの順番によっては、インターフェース名が&lt;br /&gt;
変化してしまう可能性があった。 &lt;br /&gt;
そこで、MACアドレスを使用して（簡単には）変化しないインターフェース名の&lt;br /&gt;
採用になったものと考える。&lt;span style=&quot;color: red;&quot;&gt;&lt;b&gt;（←私の勝手な推測）&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
これが、&lt;br /&gt;
&lt;span style=&quot;color: blue;&quot;&gt;&lt;b&gt;&quot;predictable network interface names&quot;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: blue;&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/span&gt;予測可能なネットワークインターフェース名の筈だ。&lt;br /&gt;
&lt;br /&gt;
つまり、順番によって変化する名前は「予測不可能」で、MACアドレスは機器に&lt;br /&gt;
固有なので「予測可能」と言うことなのだろう。&lt;br /&gt;
この変更で、&quot;dhcpcd.conf&quot;にインターフェース名を指定してIPアドレスの固定を&lt;br /&gt;
していた場合など、その再設定をしなければならなかった。&lt;br /&gt;
&lt;br /&gt;
でも、それはそれで、まあ理解できる変更だと思う。&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;それなのに、だ！&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;color: red;&quot;&gt;&lt;b&gt;その変更から1ヶ月程度で、何故か、元に戻された。&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre&gt;&quot;Disable predictable network interface names for Ethernet devices&quot;&lt;/pre&gt;
&amp;nbsp;リリースノートには上記のみで、他の説明が無いので、変更理由は不明。&lt;br /&gt;
&lt;br /&gt;
少なくとも、或るポリシーがあって変更されたシステムが簡単に戻されてしまうのは、&lt;br /&gt;
如何なものかと思いながら、eth0、wlan0形式へ&lt;span style=&quot;color: red;&quot;&gt;&lt;b&gt;再度設定を書き直す&lt;/b&gt;&lt;/span&gt;のである。&lt;br /&gt;
&lt;br /&gt;
何度かTwitterで呟いたが、&lt;br /&gt;
「updateしたら諸々動かなくなりました」ってIoTの民主化なの？&lt;br /&gt;
&amp;nbsp;&lt;a href=&quot;https://twitter.com/AO_o10yan/status/844033086383841280&quot;&gt;https://twitter.com/AO_o10yan/status/844033086383841280&lt;/a&gt;&lt;br /&gt;
&lt;span class=&quot;st&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;b&gt;&lt;span style=&quot;color: red;&quot;&gt;※追記1（2017/09/13　21:30）※&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
ここ&lt;a href=&quot;https://www.raspberrypi.org/forums/viewtopic.php?t=191639#p1204352&quot; target=&quot;_blank&quot;&gt;https://www.raspberrypi.org/forums/viewtopic.php?t=191639#p1204352&lt;/a&gt;&lt;br /&gt;
を参考にして、私の環境で確認して見たところ、やはり&lt;br /&gt;
&quot;/etc/systemd/network/99-default.link&quot;（&quot;/dev/null&quot;へのシンボリックリンク）が&lt;br /&gt;
在ると&quot;wlan0&quot;形式、無いと&quot;wlx????????????&quot;形式になるようです。&lt;br /&gt;
実は、色々といじり過ぎているので、これが本当に効いているのかは自信が有りませんが、、、。&lt;br /&gt;
&lt;b&gt;&lt;span style=&quot;color: red;&quot;&gt;※追記2（2017/09/14　22:00）※&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&quot;2017-09-07-raspbian-stretch.img&quot;をmicroSDへ焼き直して、素の状態で試して見ましたが、&lt;br /&gt;
上記の「追記1」と同じ結果を得ました。&lt;br /&gt;
尚、&quot;/etc/systemd/network/99-default.link&quot;無しの状態、詰まり&quot;wlx????????????&quot;形式の&lt;br /&gt;
表示状態から、カーネルコマンドラインに&quot;net.ifnames=0&quot;とすれば、&quot;wlan0&quot;になりました。&lt;br /&gt;
オプションの選択肢が複数あるということです。</content><link rel='replies' type='application/atom+xml' href='http://aoo10yan.blogspot.com/feeds/3191820430196596012/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://aoo10yan.blogspot.com/2017/09/raspbian-stretch.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7359781935835547652/posts/default/3191820430196596012'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7359781935835547652/posts/default/3191820430196596012'/><link rel='alternate' type='text/html' href='http://aoo10yan.blogspot.com/2017/09/raspbian-stretch.html' title='Raspbian Stretchの迷走（？）'/><author><name>AO_o10yan</name><uri>http://www.blogger.com/profile/00449541977510719198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjpFNuBkxjeQiMNUr1GgjBRtfaKJjnlQopXTl0HZ7cHqa17QJLOs_s8upEyFPChsjpMeNPIgCqjzmzr3dVRiSvu7iGNreoqWrhxdBzh0_wm17Fi6OXsHrPhZ3QrqUb61U0HTPpDj2WKIEH/s72-c/2017-09-10--1505021690_1024x768_scrot.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7359781935835547652.post-7523300703100925795</id><published>2017-05-14T16:13:00.000+09:00</published><updated>2020-03-07T15:47:04.080+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="arch"/><category scheme="http://www.blogger.com/atom/ns#" term="linux"/><category scheme="http://www.blogger.com/atom/ns#" term="opencv"/><category scheme="http://www.blogger.com/atom/ns#" term="raspberry pi"/><title type='text'>Raspberry Pi　Arch Linux ARMにOpenCV入れてみた</title><content type='html'>Arch Linux ARMにOpenCVとやらを入れてみた。&lt;br /&gt;
インストール自体は至極簡単。pacman(yaourt)任せでOK。&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-bash linenums&quot;&gt;sudo pacman -S opencv&lt;/pre&gt;Pythonで使いたいので、&quot;numpy&quot;もインストールする。&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-bash linenums&quot;&gt;sudo pacman -S python-numpy&lt;/pre&gt;&quot;numpy&quot;は、Pythonで数値計算を効率良く（高速に？）行う為のライブラリらしい。 &lt;br /&gt;
これだけで、OpenCVが使えるようになる。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglH0qG9eT7ygUvAWk7ij10KSkUEHqgvgv6kZwC6DtgCkPETCmqsdVoyWwgGoVNolXPmHzegynbbTMh1n3mZt3gase0tUXwk4P-ibESA5tryd7bJ5B66e8e9aLp4B-ArKxlqkRWD5Zx2gWx/s1600/2017-05-14--1494740374_1152x870_scrot.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;482&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglH0qG9eT7ygUvAWk7ij10KSkUEHqgvgv6kZwC6DtgCkPETCmqsdVoyWwgGoVNolXPmHzegynbbTMh1n3mZt3gase0tUXwk4P-ibESA5tryd7bJ5B66e8e9aLp4B-ArKxlqkRWD5Zx2gWx/s640/2017-05-14--1494740374_1152x870_scrot.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiz7I8jrQsz1I3J_6u7s-GXnqssh7QkpywjnTmBhf26XxW5S8zdxnL_4FJHIOEJiayMrzxuxNiYbGsOblFyYUDNwS2YSNK-kJHSLhX00an-QQ1wJQZOHBgeAEyV6r8-e0AYRhlVMUdxl7j0/s1600/2017-05-14--1494744569_819x699_scrot.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;546&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiz7I8jrQsz1I3J_6u7s-GXnqssh7QkpywjnTmBhf26XxW5S8zdxnL_4FJHIOEJiayMrzxuxNiYbGsOblFyYUDNwS2YSNK-kJHSLhX00an-QQ1wJQZOHBgeAEyV6r8-e0AYRhlVMUdxl7j0/s640/2017-05-14--1494744569_819x699_scrot.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;このようなBGR値を、操作することで画像処理を行っていく（らしい）。&lt;br /&gt;
&lt;br /&gt;
ついでなので、画像での顔検出をやってみる。&lt;br /&gt;
&lt;span style=&quot;color: blue;&quot;&gt;&lt;b&gt;下のページを参考にさせてもらいました。有り難うございます。&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;a href=&quot;http://peaceandhilightandpython.hatenablog.com/entry/2016/02/18/194303&quot; target=&quot;_blank&quot;&gt;http://peaceandhilightandpython.hatenablog.com/entry/2016/02/18/194303&lt;/a&gt;&lt;br /&gt;
（自分の環境で動くように、パスの指定等は変更しています。）&lt;br /&gt;
検出用には、OpenCVをインストールすると標準で入っている、&lt;br /&gt;
&quot;/usr/share/opencv/haarcascades/haarcascade_frontface_default.xml&quot;&lt;br /&gt;
を使用する。&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-py linenums&quot;&gt;#!/usr/bin/env python
# -*- coding:utf-8 -*-

import cv2
import numpy as np

faceCascade = cv2.CascadeClassifier(&#39;/usr/share/opencv/haarcascades/haarcascade_frontalface_default.xml&#39;)

img = cv2.imread(&#39;./face.jpg&#39;)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
face = faceCascade.detectMultiScale(gray, 1.1, 3)

if len(face) &amp;gt; 0:
    for rect in face:
    cv2.rectangle(img, tuple(rect[0:2]), tuple(rect[0:2]+rect[2:4]), (255, 255,255), thickness=2)
else:
    print(&quot;no face&quot;)

cv2.imwrite(&#39;detected.jpg&#39;, img)&lt;/pre&gt;&lt;br /&gt;
元の画像（お馴染みの）&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgyX5d7CZ8Q-8LhR7dsZltBuw7L70eYF9scnBLBYP1FI4-Ru5hSCmQT3ejA6dNuFv4Gm3-HhjSZYp5mIQfxiHNk1TXj7jedJjeKSgiQk5eJr04pTa7_vLmv15R_dh4ZYFQ4WuMAUQcXnJBR/s1600/face.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;240&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgyX5d7CZ8Q-8LhR7dsZltBuw7L70eYF9scnBLBYP1FI4-Ru5hSCmQT3ejA6dNuFv4Gm3-HhjSZYp5mIQfxiHNk1TXj7jedJjeKSgiQk5eJr04pTa7_vLmv15R_dh4ZYFQ4WuMAUQcXnJBR/s320/face.jpg&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
検出結果&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwWXgNKQjkjGQVcXCdrUEPwyCeIhvymscY0hYiUxClUupfpOUNOreoF_kgHP3C4NcGY27PBvb2T3DjylsZsg8sAxxw6X5hkpKOO5wj1fnjXM2fmMAfXmH0LnnaH-wLqBM6poVXdjl-NceE/s1600/detected.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;240&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwWXgNKQjkjGQVcXCdrUEPwyCeIhvymscY0hYiUxClUupfpOUNOreoF_kgHP3C4NcGY27PBvb2T3DjylsZsg8sAxxw6X5hkpKOO5wj1fnjXM2fmMAfXmH0LnnaH-wLqBM6poVXdjl-NceE/s320/detected.jpg&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
試しに、180度回転して上下逆にした画像で実行してみた。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvw0SFODz0kfl-fS5jk5ERQgcb05fR3iO4OZC9lucrTAFZmK6LWf9X_xP73fzxpxE4gOV9N8Qa4vvHh051yxWKbdph7srZCJc0Fd8w_gFkYpttqtUwNcuOs0bPSb-dsBt_s5Bh2OuV7j9P/s1600/upside_down.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;240&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvw0SFODz0kfl-fS5jk5ERQgcb05fR3iO4OZC9lucrTAFZmK6LWf9X_xP73fzxpxE4gOV9N8Qa4vvHh051yxWKbdph7srZCJc0Fd8w_gFkYpttqtUwNcuOs0bPSb-dsBt_s5Bh2OuV7j9P/s320/upside_down.jpg&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;これは、&quot;no face&quot;となり、検出できなかった。&lt;br /&gt;
&lt;br /&gt;
</content><link rel='replies' type='application/atom+xml' href='http://aoo10yan.blogspot.com/feeds/7523300703100925795/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://aoo10yan.blogspot.com/2017/05/raspberry-piarch-linux-armopencv.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7359781935835547652/posts/default/7523300703100925795'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7359781935835547652/posts/default/7523300703100925795'/><link rel='alternate' type='text/html' href='http://aoo10yan.blogspot.com/2017/05/raspberry-piarch-linux-armopencv.html' title='Raspberry Pi　Arch Linux ARMにOpenCV入れてみた'/><author><name>AO_o10yan</name><uri>http://www.blogger.com/profile/00449541977510719198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglH0qG9eT7ygUvAWk7ij10KSkUEHqgvgv6kZwC6DtgCkPETCmqsdVoyWwgGoVNolXPmHzegynbbTMh1n3mZt3gase0tUXwk4P-ibESA5tryd7bJ5B66e8e9aLp4B-ArKxlqkRWD5Zx2gWx/s72-c/2017-05-14--1494740374_1152x870_scrot.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7359781935835547652.post-8534436709029217073</id><published>2017-05-05T13:17:00.001+09:00</published><updated>2017-05-06T22:14:02.835+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="arch"/><category scheme="http://www.blogger.com/atom/ns#" term="gtkdialog"/><category scheme="http://www.blogger.com/atom/ns#" term="linux"/><category scheme="http://www.blogger.com/atom/ns#" term="quadruped"/><category scheme="http://www.blogger.com/atom/ns#" term="raspberry pi"/><category scheme="http://www.blogger.com/atom/ns#" term="robot"/><category scheme="http://www.blogger.com/atom/ns#" term="servoblaster"/><title type='text'>「簡易ポーズエディタ」　遂に、ボタンを使う</title><content type='html'>&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;iframe allowfullscreen=&quot;&quot; class=&quot;YOUTUBE-iframe-video&quot; data-thumbnail-src=&quot;https://i.ytimg.com/vi/mifcYykjNAE/0.jpg&quot; frameborder=&quot;0&quot; height=&quot;266&quot; src=&quot;https://www.youtube.com/embed/mifcYykjNAE?feature=player_embedded&quot; width=&quot;320&quot;&gt;&lt;/iframe&gt;&lt;iframe allowfullscreen=&quot;&quot; class=&quot;YOUTUBE-iframe-video&quot; data-thumbnail-src=&quot;https://i.ytimg.com/vi/_ggzrTQiGYk/0.jpg&quot; frameborder=&quot;0&quot; height=&quot;266&quot; src=&quot;https://www.youtube.com/embed/_ggzrTQiGYk?feature=player_embedded&quot; width=&quot;320&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;br /&gt;
Raspberry Pi 2 Model B + ServoBlaster + シェルスクリプト（GtkDialog）で4足歩行ロボットを操作。&lt;br /&gt;
「簡易ポーズエディタ」の、今まで飾りになっていた上部のボタンに、機能を持たせた。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5JrKaCifqkIeAe0kf-_oZsChUQAyhy9SlB5SLHJvCyM7Uh52IsPbYTI-fsbkvpixtRznFCQ1y0JqBdn3vQMecCA3XfPGXp4NvlDmdmMjBxhXEaQXtabppnYlSzvksRdxUkQixkY2Wr4pj/s1600/2017-05-04--1493863451_1152x870_scrot.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;481&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5JrKaCifqkIeAe0kf-_oZsChUQAyhy9SlB5SLHJvCyM7Uh52IsPbYTI-fsbkvpixtRznFCQ1y0JqBdn3vQMecCA3XfPGXp4NvlDmdmMjBxhXEaQXtabppnYlSzvksRdxUkQixkY2Wr4pj/s640/2017-05-04--1493863451_1152x870_scrot.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
「左回転」「前進」「後退」「右回転」のボタンでそれぞれの動作を起動する。&lt;br /&gt;
（GtkDialogから、別のシェルスクリプトに書かれたfunction呼んでいるだけ）&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsM8Fa3dvNViD2gemhVlHJ6h7TSaHPSuDLPLEceVncp_uRRaadV_bdb5m1fMT2Zgkoy5zTp516R0NHxZTC5snLnBpbUFMEpUYhOyrw11D3GeSiWRFbEEP4pUUAdcSbXj61C67vpQf7bQYq/s1600/2017-05-04--1493869037_986x595_scrot.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;386&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsM8Fa3dvNViD2gemhVlHJ6h7TSaHPSuDLPLEceVncp_uRRaadV_bdb5m1fMT2Zgkoy5zTp516R0NHxZTC5snLnBpbUFMEpUYhOyrw11D3GeSiWRFbEEP4pUUAdcSbXj61C67vpQf7bQYq/s640/2017-05-04--1493869037_986x595_scrot.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
ただし、「停止」ボタンを押さない限り、繰り返し回数上限まで動作を続行する。&lt;br /&gt;
&lt;br /&gt;
ヘボいのは、上限に達して終了しても、操作ボタンがグレイアウトから復帰しない点。&lt;br /&gt;
「停止」ボタンを押さないと、復帰しない。</content><link rel='replies' type='application/atom+xml' href='http://aoo10yan.blogspot.com/feeds/8534436709029217073/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://aoo10yan.blogspot.com/2017/05/blog-post.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7359781935835547652/posts/default/8534436709029217073'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7359781935835547652/posts/default/8534436709029217073'/><link rel='alternate' type='text/html' href='http://aoo10yan.blogspot.com/2017/05/blog-post.html' title='「簡易ポーズエディタ」　遂に、ボタンを使う'/><author><name>AO_o10yan</name><uri>http://www.blogger.com/profile/00449541977510719198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img.youtube.com/vi/mifcYykjNAE/default.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7359781935835547652.post-6584637122298718049</id><published>2017-03-26T16:29:00.000+09:00</published><updated>2020-03-07T15:52:15.462+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="arch"/><category scheme="http://www.blogger.com/atom/ns#" term="linux"/><category scheme="http://www.blogger.com/atom/ns#" term="raspberry pi"/><category scheme="http://www.blogger.com/atom/ns#" term="servoblaster"/><title type='text'>Raspberry Pi kernel 4.9でServoBlaster（その2　非推奨）</title><content type='html'>&lt;a href=&quot;http://aoo10yan.blogspot.jp/2017/03/kernel-49servoblaster.html&quot;&gt;前回の暫定的な処置&lt;/a&gt;を少し変更。&lt;br /&gt;
&quot;/proc/cpuinfo&quot;の&quot;Hardware&quot;情報を元にする方法はkernel 4.9では通用しないので、&lt;br /&gt;
&quot;/proc/device-tree/soc/ranges&quot;を読み込んで、&quot;board_model&quot;を判定するように変更してみた。&lt;br /&gt;
&lt;br /&gt;
参考：下のリンク、&lt;span style=&quot;color: blue;&quot;&gt;&lt;b&gt;pelwell&lt;/b&gt;&lt;/span&gt;さんのコメントを参考にしました。&lt;br /&gt;
&lt;a href=&quot;https://github.com/raspberrypi/linux/issues/1902#issuecomment-287365600&quot;&gt;https://github.com/raspberrypi/linux/issues/1902#issuecomment-287365600&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&lt;span style=&quot;font-size: medium;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: red;&quot;&gt;※以下は非推奨です！！ Raspberry Pi 2 Model Bでしか確認していません！※ &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&quot;servod.c&quot;をエディタで開き、958行目からの&lt;br /&gt;
&lt;pre class=&quot;prettyprint lamg-c linenums&quot;&gt;if (strstr(modelstr, &quot;BCM2708&quot;))
            board_model = 1;
else if (strstr(modelstr, &quot;BCM2709&quot;))
            board_model = 2;
else
            fatal(&quot;servod: Cannot parse the hardware name string\n&quot;);
&lt;/pre&gt;ここを下のように書き換える。&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-c linenums&quot;&gt;char buffer[5];
  FILE *file;
        
  file = fopen(&quot;/proc/device-tree/soc/ranges&quot;, &quot;rb&quot;);
  fread(buffer, 1, sizeof(buffer), file);
  fclose(file);

  if (buffer[4] == 0x20)
        board_model = 1;
  else if (buffer[4] == 0x3f)
        board_model = 2;
  else
        fatal(&quot;servod: Cannot parse the board model\n&quot;);
&lt;/pre&gt;&lt;b&gt;&lt;span style=&quot;color: red;&quot;&gt;※追記1（2017/04/22　20:20）※&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;span style=&quot;color: blue;&quot;&gt;本当は&quot;hardware name&quot;を読んでいる訳ではないので、最後のメーッセージは&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: blue;&quot;&gt;&quot;servod: Cannot parse the board model\n&quot;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: blue;&quot;&gt;&amp;nbsp;とでもすれば良いですかね&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style=&quot;color: red;&quot;&gt;※追記2（2017/04/27　20:25）※&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&quot;char buffer[8]&quot;から&quot;char buffer[5] &quot;へ変更&lt;br /&gt;
&lt;br /&gt;
以前の&quot;servod&quot;を削除して、改めて&quot;make&quot;し、&quot;servod&quot;を起動する。&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHtl1o2yvc_S7NkImwSTAJGBPHV4Y0pMwuZgRqdNa6npGU2ugGXin2Cl4e6-Uqv7BUpOc0E5qqcFSNQqB2jqZ8vjtmwgJCAt9xrJYjIv946sHG0oHOOSMELwne568Tsx2D0-gq_idjxF11/s1600/2017-03-26--1490508824_1024x768_scrot.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;480&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHtl1o2yvc_S7NkImwSTAJGBPHV4Y0pMwuZgRqdNa6npGU2ugGXin2Cl4e6-Uqv7BUpOc0E5qqcFSNQqB2jqZ8vjtmwgJCAt9xrJYjIv946sHG0oHOOSMELwne568Tsx2D0-gq_idjxF11/s640/2017-03-26--1490508824_1024x768_scrot.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVoOMhY3_2Xj5dpmjUoJHcWYBmbLb1Rl7DeRa91qeZMGGdaRnVQdyq-YmsuxGQ0GQx3ozakYXHbcplgC-HPemlzyThPY0SqkkOtQkAoE5j40l9nGu9rExSpdXjqFDKmVG6-WlbBp9525rz/s1600/2017-03-26--1490508783_874x657_scrot.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;481&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVoOMhY3_2Xj5dpmjUoJHcWYBmbLb1Rl7DeRa91qeZMGGdaRnVQdyq-YmsuxGQ0GQx3ozakYXHbcplgC-HPemlzyThPY0SqkkOtQkAoE5j40l9nGu9rExSpdXjqFDKmVG6-WlbBp9525rz/s640/2017-03-26--1490508783_874x657_scrot.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;b&gt;&lt;span style=&quot;color: red;&quot;&gt;※追記3（2017/05/03　21:40）※&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
下記にて、&quot;/proc/device-tree/soc/ranges&quot;を開けなかった場合の処理を追加。&lt;br /&gt;
fseekでファイル読込開始位置を指定し、配列への読み込みを限定してみた。&lt;br /&gt;
（特に意味は無い）&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-c linenums&quot;&gt;char buffer[1];
  FILE *file;
 
  file = fopen(&quot;/proc/device-tree/soc/ranges&quot;, &quot;rb&quot;);
 
  if (!file)
        fatal(&quot;Unable to open /proc/device-tree/soc/ranges: %m\n&quot;);
 
  fseek(file, 4, SEEK_SET);
  fread(buffer, 1, sizeof(buffer), file);
  fclose(file);

  if (buffer[0] == 0x20)
        board_model = 1;
  else if (buffer[0] == 0x3f)
        board_model = 2;
  else
        fatal(&quot;servod: Cannot parse the board model\n&quot;);
&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://aoo10yan.blogspot.com/feeds/6584637122298718049/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://aoo10yan.blogspot.com/2017/03/raspberry-pi-kernel-49servoblaster.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7359781935835547652/posts/default/6584637122298718049'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7359781935835547652/posts/default/6584637122298718049'/><link rel='alternate' type='text/html' href='http://aoo10yan.blogspot.com/2017/03/raspberry-pi-kernel-49servoblaster.html' title='Raspberry Pi kernel 4.9でServoBlaster（その2　非推奨）'/><author><name>AO_o10yan</name><uri>http://www.blogger.com/profile/00449541977510719198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHtl1o2yvc_S7NkImwSTAJGBPHV4Y0pMwuZgRqdNa6npGU2ugGXin2Cl4e6-Uqv7BUpOc0E5qqcFSNQqB2jqZ8vjtmwgJCAt9xrJYjIv946sHG0oHOOSMELwne568Tsx2D0-gq_idjxF11/s72-c/2017-03-26--1490508824_1024x768_scrot.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7359781935835547652.post-582963250719322576</id><published>2017-03-13T18:41:00.001+09:00</published><updated>2020-03-07T15:54:07.326+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="arch"/><category scheme="http://www.blogger.com/atom/ns#" term="linux"/><category scheme="http://www.blogger.com/atom/ns#" term="raspberry pi"/><category scheme="http://www.blogger.com/atom/ns#" term="servoblaster"/><title type='text'>ラズパイ kernel 4.9でServoBlaster（非推奨）</title><content type='html'>Raspberry Pi 2 Model Bで使っているArch Linux ARMのkernelが、4.9系に上がりましたが、、、。&lt;br /&gt;
ServoBlasterは4.9系に対応しておらず、&lt;br /&gt;
&quot;servod: Cannot parse the hardware name string&quot;&lt;br /&gt;
エラーを吐いて起動しません。&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTOA8OywjbQjOH2YDs5O5UmPY6yzJSvBDkzxiVxzglKFS1hx24Akw0lzLLhGwF_V2F6QYNDk_bRDet6ADK8Uq5N8W9l-dZAB_PgnUqpgNbAm8LQssUQK2NUBlyRu7dOgab16iqLar6HI5H/s1600/2017-03-13--1489396495_818x536_scrot.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTOA8OywjbQjOH2YDs5O5UmPY6yzJSvBDkzxiVxzglKFS1hx24Akw0lzLLhGwF_V2F6QYNDk_bRDet6ADK8Uq5N8W9l-dZAB_PgnUqpgNbAm8LQssUQK2NUBlyRu7dOgab16iqLar6HI5H/s1600/2017-03-13--1489396495_818x536_scrot.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
ServoBlasterは、&quot;/proc/cpuinfo&quot;から情報を取ってRaspberry Piの&lt;strike&gt;機種&lt;/strike&gt;ボードモデルを判別しているらしいのですが、&lt;br /&gt;
kernel 4.9になってから、&quot;/proc/cpuinfo&quot;での情報が変わったようです。&lt;br /&gt;
これに対応させるように、&lt;b&gt;&lt;span style=&quot;color: red;&quot;&gt;応急処置&lt;/span&gt;&lt;/b&gt;をしてみました。&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: red;&quot;&gt;※追記1（2017/03/26　16:55）※&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: red; font-size: large;&quot;&gt;Raspberry Piのボードモデル判別の方法を&lt;b&gt;修正&lt;/b&gt;したものが、次にあります。&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: red;&quot;&gt;&lt;a href=&quot;http://aoo10yan.blogspot.jp/2017/03/raspberry-pi-kernel-49servoblaster.html&quot;&gt;&amp;nbsp;http://aoo10yan.blogspot.jp/2017/03/raspberry-pi-kernel-49servoblaster.html&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: red;&quot;&gt;※以下は非推奨です！！ Raspberry Pi 2 Model Bでしか確認していません！※ &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&quot;servod.c&quot;をエディタで開き、&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-c linenums&quot;&gt;else if (strstr(modelstr, &quot;BCM2709&quot;))&lt;/pre&gt;この行を下のように書き換える。&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-c linenums&quot;&gt;else if (strstr(modelstr, &quot;BCM2709&quot;) || strstr(modelstr, &quot;BCM2835&quot;))&lt;/pre&gt;以前の&quot;servod&quot;を削除して、改めて&quot;make&quot;し、&quot;servod&quot;を起動する。&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6_HCKET9XJhXSzKdpNI5nKTgtNBA5_ZLvAatbwebBWd8cUF0JJDC9bKiKFy8XUNYKQ27NYgw8zNEFj6V5jK2u-6X33R7V8PwWT-nAuwQkurS8XDACC4OMQSfvQ_hqCHQWo5Loer1TBrZg/s1600/2017-03-13--1489397979_588x632_scrot.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6_HCKET9XJhXSzKdpNI5nKTgtNBA5_ZLvAatbwebBWd8cUF0JJDC9bKiKFy8XUNYKQ27NYgw8zNEFj6V5jK2u-6X33R7V8PwWT-nAuwQkurS8XDACC4OMQSfvQ_hqCHQWo5Loer1TBrZg/s1600/2017-03-13--1489397979_588x632_scrot.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
自分の環境では、これで動きました。</content><link rel='replies' type='application/atom+xml' href='http://aoo10yan.blogspot.com/feeds/582963250719322576/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://aoo10yan.blogspot.com/2017/03/kernel-49servoblaster.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7359781935835547652/posts/default/582963250719322576'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7359781935835547652/posts/default/582963250719322576'/><link rel='alternate' type='text/html' href='http://aoo10yan.blogspot.com/2017/03/kernel-49servoblaster.html' title='ラズパイ kernel 4.9でServoBlaster（非推奨）'/><author><name>AO_o10yan</name><uri>http://www.blogger.com/profile/00449541977510719198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTOA8OywjbQjOH2YDs5O5UmPY6yzJSvBDkzxiVxzglKFS1hx24Akw0lzLLhGwF_V2F6QYNDk_bRDet6ADK8Uq5N8W9l-dZAB_PgnUqpgNbAm8LQssUQK2NUBlyRu7dOgab16iqLar6HI5H/s72-c/2017-03-13--1489396495_818x536_scrot.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7359781935835547652.post-8524369382525903742</id><published>2017-03-10T20:53:00.000+09:00</published><updated>2020-03-07T15:56:51.491+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="arch"/><category scheme="http://www.blogger.com/atom/ns#" term="linux"/><category scheme="http://www.blogger.com/atom/ns#" term="raspberry pi"/><category scheme="http://www.blogger.com/atom/ns#" term="scratch"/><title type='text'>Scratch 1.4へテキストファイルを読み込む</title><content type='html'>&lt;a href=&quot;http://aoo10yan.blogspot.jp/2017/03/scratch-14.html&quot;&gt;前回、Scratchのブロックを追加して、Linuxコマンドを送るようにした&lt;/a&gt;ので、&lt;br /&gt;
コマンドの出力結果をScratchへ読み込むブロックも作ってみる。&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: small;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: red;&quot;&gt;※言うまでもないですが、Scratchの改造は自己責任で！※&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
通常は、直接外部ファイルを読み込むためのブロックは用意されていないので、&lt;br /&gt;
ScratchをSmalltalkのレベルで改造する必要があり、以下を参考にして、&lt;br /&gt;
ブロックの追加を行った。情報を公開してくださった方々に感謝。&lt;br /&gt;
&lt;b&gt;参考&lt;/b&gt;&lt;br /&gt;
&lt;a href=&quot;http://itpro.nikkeibp.co.jp/article/COLUMN/20111019/371085/&quot;&gt;http://itpro.nikkeibp.co.jp/article/COLUMN/20111019/371085/&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://oohito.com/nqthm/archives/2243&quot;&gt;http://oohito.com/nqthm/archives/2243&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://d.hatena.ne.jp/minekoa/20080314/1205484707&quot;&gt;http://d.hatena.ne.jp/minekoa/20080314/1205484707&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ブロックの追加。&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint linenums&quot;&gt;(&#39;addFile %s to %L&#39; #- #addfile:toList: &#39;filename&#39;)&lt;/pre&gt;&lt;br /&gt;
外部ファイルを読み込んで、Scratch側のリストに追加するメソッドを設定する。&lt;br /&gt;
読み込むファイルまでのパスを抽出し 、空ならデフォルトのパスにする。&lt;br /&gt;
空でなければ、抽出したパスを使う。その上でファイルの有無を確認して処理を進める。&lt;br /&gt;
一行ごとに指定したリストに追加して行く。&lt;br /&gt;
この、リストに追加して行く処理は、まるごとScratchの&lt;span style=&quot;background-color: #cc0000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: white;&quot;&gt;「（なにか）を（リスト）に追加する」&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;を&lt;br /&gt;
利用する。&lt;br /&gt;
&lt;br /&gt;
リストに追加して行く処理を考えている最中に、内容をTwitterにつぶやいたところ、&lt;br /&gt;
Smalltalkに詳しい&lt;a href=&quot;https://twitter.com/sumim&quot;&gt;sumimさん&lt;/a&gt;からスマートな方法をご教示頂きました。 有難うございました。&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint linenums&quot;&gt;addfile: t1 toList: t2 
    | path file |
    path _ FileDirectory dirPathFor: t1.
    path = &#39;&#39; ifTrue: [path _ FileDirectory default pathName].
    ((FileDirectory on: path)
        fileExists: t1)
        ifTrue: 
            [file _ FileStream readOnlyFileNamed: t1.
            file contentsOfEntireFile lines do: [:line | self append: line toList: t2]]
&lt;/pre&gt;&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAbasp-ra7Cq4sz-XR2ivEWm-dQtQkaZIWpKkuRH5XpKh2DhhNbrs75VPvm3FftTNlHIEMDCtMJXXuXCO6REe27zbBrmD0AXdsxh6IOstaOJf3c_qVJS3kLJWaIW1UDSyc6fzUqShtxA8T/s1600/2017-03-11--1489197987_595x282_scrot.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAbasp-ra7Cq4sz-XR2ivEWm-dQtQkaZIWpKkuRH5XpKh2DhhNbrs75VPvm3FftTNlHIEMDCtMJXXuXCO6REe27zbBrmD0AXdsxh6IOstaOJf3c_qVJS3kLJWaIW1UDSyc6fzUqShtxA8T/s1600/2017-03-11--1489197987_595x282_scrot.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
先に格納用のリストを作っておく。&lt;br /&gt;
前回追加したブロックで、コマンドの出力をファイルにリダイレクトする文字列を実行。&lt;br /&gt;
リダイレクトで指定したファイルを、格納用のリストに追加するように実行。&lt;br /&gt;
&lt;br /&gt;
&quot;ls &amp;gt; /home/o10yan/lstest.txt&quot;で&quot;ls&quot;コマンドの結果をファイルにして、&lt;br /&gt;
それをScratchのリストに読み込む一連の流れをやってみた。 &lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjsn_YGR3ClrsFP3m8ILzQoQ820tRY0tcMQk5gXOs9QIhVBQnO2MQTlCGdTuwxWjqme0_x3df86s_J9-oGnwodvefPSVvfPCNlq8Z1Aipds5j8upruTljhSLSssR2IEx7nU2ej_-GNiY1jm/s1600/2017-03-10--1489146173_629x293_scrot.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjsn_YGR3ClrsFP3m8ILzQoQ820tRY0tcMQk5gXOs9QIhVBQnO2MQTlCGdTuwxWjqme0_x3df86s_J9-oGnwodvefPSVvfPCNlq8Z1Aipds5j8upruTljhSLSssR2IEx7nU2ej_-GNiY1jm/s1600/2017-03-10--1489146173_629x293_scrot.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAWGdOmwkzwxkDfNmvLrxnYlg7I3S9wDqvjzwu41jVWpQenaFxVPTd1kxG8sMZ6xAujaLm4W7sMQIs6ui-zXXZ3sSobt7QQt1ophTtV9fUJiPR_muDM6HOt8TtqWicj6vIoy95V1N9SbCE/s1600/2017-03-10--1489146545_773x359_scrot.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAWGdOmwkzwxkDfNmvLrxnYlg7I3S9wDqvjzwu41jVWpQenaFxVPTd1kxG8sMZ6xAujaLm4W7sMQIs6ui-zXXZ3sSobt7QQt1ophTtV9fUJiPR_muDM6HOt8TtqWicj6vIoy95V1N9SbCE/s1600/2017-03-10--1489146545_773x359_scrot.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
勿論、出力結果にこだわらなくても、平文テキストファイルの読み込み用としても使える。&lt;br /&gt;
&lt;br /&gt;
</content><link rel='replies' type='application/atom+xml' href='http://aoo10yan.blogspot.com/feeds/8524369382525903742/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://aoo10yan.blogspot.com/2017/03/scratch-14_10.html#comment-form' title='1 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7359781935835547652/posts/default/8524369382525903742'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7359781935835547652/posts/default/8524369382525903742'/><link rel='alternate' type='text/html' href='http://aoo10yan.blogspot.com/2017/03/scratch-14_10.html' title='Scratch 1.4へテキストファイルを読み込む'/><author><name>AO_o10yan</name><uri>http://www.blogger.com/profile/00449541977510719198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAbasp-ra7Cq4sz-XR2ivEWm-dQtQkaZIWpKkuRH5XpKh2DhhNbrs75VPvm3FftTNlHIEMDCtMJXXuXCO6REe27zbBrmD0AXdsxh6IOstaOJf3c_qVJS3kLJWaIW1UDSyc6fzUqShtxA8T/s72-c/2017-03-11--1489197987_595x282_scrot.png" height="72" width="72"/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7359781935835547652.post-2600927563690947758</id><published>2017-03-05T09:01:00.001+09:00</published><updated>2020-03-07T15:59:25.553+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="arch"/><category scheme="http://www.blogger.com/atom/ns#" term="linux"/><category scheme="http://www.blogger.com/atom/ns#" term="raspberry pi"/><category scheme="http://www.blogger.com/atom/ns#" term="scratch"/><title type='text'>Scratch 1.4からLinuxコマンドを使う</title><content type='html'>&lt;a href=&quot;http://aoo10yan.blogspot.jp/2017/03/scratch-14servoblaster.html&quot;&gt;前回では、ServoBlasterと言う限られた条件化で動かした&lt;/a&gt;が、&lt;br /&gt;
少しだけ書き換えて、Linuxコマンド全般を使えるようにしてみる。&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: small;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: red;&quot;&gt;※言うまでもないですが、Scratchの改造・シェルスクリプトの実行は自己責任で！※&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
通常は、直接Linuxコマンドを動かすためのブロックは用意されていないので、&lt;br /&gt;
ScratchをSmalltalkのレベルで改造する必要があり、以下を参考にして、&lt;br /&gt;
ブロックの追加を行った。情報を公開してくださった方々に感謝。&lt;br /&gt;
&lt;b&gt;参考&lt;/b&gt;&lt;br /&gt;
&lt;a href=&quot;http://itpro.nikkeibp.co.jp/article/COLUMN/20111019/371085/&quot;&gt;http://itpro.nikkeibp.co.jp/article/COLUMN/20111019/371085/&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://oohito.com/nqthm/archives/2243&quot;&gt;http://oohito.com/nqthm/archives/2243&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://d.hatena.ne.jp/minekoa/20080314/1205484707&quot;&gt;http://d.hatena.ne.jp/minekoa/20080314/1205484707&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ブロックの追加。&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint linenums&quot;&gt;(&#39;shell %s&#39; #- #shell: &#39;&#39;)&lt;/pre&gt;&lt;br /&gt;
メソッドで、保存するファイル名を変更。&lt;br /&gt;
&lt;b&gt;&lt;span style=&quot;color: red;&quot;&gt;（ホームディレクトリは私の環境の場合なので、そこは御自分の環境に読み替えて下さい） &lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint linenums&quot;&gt;shell: t1 
    | file |
    file _ FileStream fileNamed: &#39;/home/o10yan/Scratch/shell&#39;.
    file nextPutAll: t1.
    file close.
    (Delay forMilliseconds: 100) wait
&lt;/pre&gt;&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIUoFyw1gkMNli-2V-ypNmoOYPLgBz2w2RtOg80jc1qcplfPNRS2C35Bs1MbmnLoAEfMfmZhkmCsi-AzfcA2wFmbdJHwuwwFSRdbc_wAyxK0YM-N4yb5o7_0jKyYP4U9Xn5WINiFFfa7hm/s1600/2017-03-11--1489200834_600x213_scrot.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIUoFyw1gkMNli-2V-ypNmoOYPLgBz2w2RtOg80jc1qcplfPNRS2C35Bs1MbmnLoAEfMfmZhkmCsi-AzfcA2wFmbdJHwuwwFSRdbc_wAyxK0YM-N4yb5o7_0jKyYP4U9Xn5WINiFFfa7hm/s1600/2017-03-11--1489200834_600x213_scrot.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
シェルスクリプトの指定ファイルも変更。&lt;br /&gt;
読み込んだ文字列（コマンド）をそのまま&quot;eval&quot;で評価して実行。&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-bash linenums&quot;&gt;#!/bin/bash

if [ ! -e /home/o10yan/Scratch/shell ]; then
    touch /home/o10yan/Scratch/shell
fi

while inotifywait -e modify /home/o10yan/Scratch/shell; do
    text_line=$(cat /home/o10yan/Scratch/shell)

    if [ -n &#39;$text_line&#39; ]; then
         echo &#39;&#39; &amp;gt; /home//o10yan/Scratch/shell
         eval $text_line
    fi
done
&lt;/pre&gt;&lt;br /&gt;
&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_7caQ3NA-jTEW8agIkKFU5jBI-EEOrjh2wBtfEixZMr1Fwa1WSM5uY3cOJ0mKyl1JYv7h-pKMNhIIQzKv6DZsbGUuXBhz0nqbEuBG8wUrWXKVFszn8KTwLpKBqDzxE7AOzgyQDsL58xhH/s1600/2017-03-04--1488617332_1152x870_scrot.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;481&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_7caQ3NA-jTEW8agIkKFU5jBI-EEOrjh2wBtfEixZMr1Fwa1WSM5uY3cOJ0mKyl1JYv7h-pKMNhIIQzKv6DZsbGUuXBhz0nqbEuBG8wUrWXKVFszn8KTwLpKBqDzxE7AOzgyQDsL58xhH/s640/2017-03-04--1488617332_1152x870_scrot.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Scratchから&quot;gpio readall&quot;を送って見たところ&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgi5IO6Vtxe9a_k_TKPh-LV4Saw-KQnrT2e7eF8sHHwhtvwt8MssMqd6Tkwj7-OFY4zdyuof0kmoNR691uJ83z8uIrIVT4aN_AhQ9hHoraijixpAKbrJm5Es7a0zAjEI4rE4CQNRFfuzyDT/s1600/C51dveDVUAk8gd_.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;512&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgi5IO6Vtxe9a_k_TKPh-LV4Saw-KQnrT2e7eF8sHHwhtvwt8MssMqd6Tkwj7-OFY4zdyuof0kmoNR691uJ83z8uIrIVT4aN_AhQ9hHoraijixpAKbrJm5Es7a0zAjEI4rE4CQNRFfuzyDT/s640/C51dveDVUAk8gd_.jpg&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;SLを走らせてみた&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
&lt;b&gt;まとめ&lt;/b&gt; &lt;br /&gt;
やってることは非常に単純。&lt;br /&gt;
Scratchから文字列をファイルに保存する。&lt;br /&gt;
シェルスクリプトで、文字列をコマンドとして実行する。&lt;br /&gt;
&lt;br /&gt;
現実的には、「遠隔センサー接続」を利用したり、&lt;b&gt;&lt;a href=&quot;http://heppg.de/ikg/wordpress/?page_id=6&quot;&gt;scratchClient &lt;/a&gt;&lt;/b&gt;と言うソフトで&lt;br /&gt;
できるようなので、そちらを使った方が楽だと思います。&lt;br /&gt;
が、実験としては、面白かったです。&lt;br /&gt;
&lt;br /&gt;
</content><link rel='replies' type='application/atom+xml' href='http://aoo10yan.blogspot.com/feeds/2600927563690947758/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://aoo10yan.blogspot.com/2017/03/scratch-14.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7359781935835547652/posts/default/2600927563690947758'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7359781935835547652/posts/default/2600927563690947758'/><link rel='alternate' type='text/html' href='http://aoo10yan.blogspot.com/2017/03/scratch-14.html' title='Scratch 1.4からLinuxコマンドを使う'/><author><name>AO_o10yan</name><uri>http://www.blogger.com/profile/00449541977510719198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIUoFyw1gkMNli-2V-ypNmoOYPLgBz2w2RtOg80jc1qcplfPNRS2C35Bs1MbmnLoAEfMfmZhkmCsi-AzfcA2wFmbdJHwuwwFSRdbc_wAyxK0YM-N4yb5o7_0jKyYP4U9Xn5WINiFFfa7hm/s72-c/2017-03-11--1489200834_600x213_scrot.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7359781935835547652.post-1817638892044456989</id><published>2017-03-03T14:08:00.001+09:00</published><updated>2020-03-07T16:05:11.869+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="arch"/><category scheme="http://www.blogger.com/atom/ns#" term="linux"/><category scheme="http://www.blogger.com/atom/ns#" term="raspberry pi"/><category scheme="http://www.blogger.com/atom/ns#" term="scratch"/><category scheme="http://www.blogger.com/atom/ns#" term="servoblaster"/><title type='text'>Scratch 1.4からServoBlasterを使う</title><content type='html'>Arch Linux ARMに入っているScratch 1.4のブロックを使ってServoBlasterを動かそうという試み。&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: small;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: red;&quot;&gt;※言うまでもないですが、Scratchの改造・シェルスクリプトの実行は自己責任で！※&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
通常は、直接ServoBlasterを動かすためのブロックは用意されていないので、&lt;br /&gt;
ScratchをSmalltalkのレベルで改造する必要があり、以下を参考にして、&lt;br /&gt;
ブロックの追加を行った。情報を公開してくださった方々に感謝。&lt;br /&gt;
&lt;b&gt;参考&lt;/b&gt;&lt;br /&gt;
&lt;a href=&quot;http://itpro.nikkeibp.co.jp/article/COLUMN/20111019/371085/&quot;&gt;http://itpro.nikkeibp.co.jp/article/COLUMN/20111019/371085/&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://oohito.com/nqthm/archives/2243&quot;&gt;http://oohito.com/nqthm/archives/2243&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://d.hatena.ne.jp/minekoa/20080314/1205484707&quot;&gt;http://d.hatena.ne.jp/minekoa/20080314/1205484707&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;概要&lt;/b&gt;&lt;br /&gt;
ServoBlasterは、&quot;echo 0=50% &amp;gt; /dev/servoblaster&quot;と言った形式のコマンドで、&lt;br /&gt;
&quot;/dev/servoblaster&quot;に値を送る事でサーボモータを動かす。 &lt;br /&gt;
&amp;nbsp;なので、Scratch側から上記のコマンド相当（ファイルへの書き込み）を実行できれば、&lt;br /&gt;
ServoBlasterが動くはず。&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;color: blue;&quot;&gt;&lt;b&gt;だったが、、、。&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
やってみたところ、Scratchで直接ファイル（/dev/servoblaster）への書き込みを&lt;br /&gt;
実行しても、ServoBlasterで拾わなかった。&lt;br /&gt;
そこで、Scratch外部のシェルスクリプトから&quot;echo 0=50% &amp;gt; /dev/servoblaster&quot;を送ってみた。&lt;br /&gt;
動作確認ができたので、この方法を使うことにした。 &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;手順&lt;/b&gt;&lt;br /&gt;
①・ScratchからSmalltalkへ降りて、ブロックの追加をする。&lt;br /&gt;
②・追加したブロックに任意のファイルへの書き込みのメソッド（？）を設定する。 &lt;br /&gt;
③・任意のファイルの更新を監視し、変更があった場合にファイル内容（文字列）を読み込んで、&lt;br /&gt;
&quot;echo&quot;コマンドで&quot;/dev/servoblaster&quot;へ送る為のシェルスクリプトを作成する。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
手順①は上述の参考サイトを見て、適当なブロックのカテゴリに追加。&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrM3-Oo85V08_DgAZhY5omdxrrGFFA2HUG0S_p0uOgOZB0xDCRE4SujRFDT7awPJ4gflbKY3uvXlrMdlpLIggIA7_-nb0sDcR_cbydnZC7wu_6XqvWnxCqEOAqIPzR4l6wKStz17bgbDrS/s1600/2017-03-04--1488612179_598x402_scrot.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrM3-Oo85V08_DgAZhY5omdxrrGFFA2HUG0S_p0uOgOZB0xDCRE4SujRFDT7awPJ4gflbKY3uvXlrMdlpLIggIA7_-nb0sDcR_cbydnZC7wu_6XqvWnxCqEOAqIPzR4l6wKStz17bgbDrS/s1600/2017-03-04--1488612179_598x402_scrot.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;pre class=&quot;prettyprint linenums&quot;&gt;(&#39;servo %s&#39; #- #servo: &#39;0=50%&#39;)&lt;/pre&gt;&lt;br /&gt;
ブロックができたことを確認。 &lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjR0FBgVUJxaaakP56jh7-TYfJ13wxLaER4CsG6PnQ6Rh93RJ4pK4Ww2FkkkGe1NvLBe-4Hn7n48Wat7wh-rBmE-pTcFpKNOSTfMSIS4CWF4X0fxtCITg_DpX2GScdDc7IszkdsVov5__3y/s1600/2017-03-04--1488612233_216x238_scrot.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjR0FBgVUJxaaakP56jh7-TYfJ13wxLaER4CsG6PnQ6Rh93RJ4pK4Ww2FkkkGe1NvLBe-4Hn7n48Wat7wh-rBmE-pTcFpKNOSTfMSIS4CWF4X0fxtCITg_DpX2GScdDc7IszkdsVov5__3y/s1600/2017-03-04--1488612233_216x238_scrot.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
手順②では、今回は任意のファイルを&quot;/home/o10yan/Scratch/servo&quot;と決めうちする。&lt;br /&gt;
&lt;b&gt;&lt;span style=&quot;color: red;&quot;&gt;（ホームディレクトリは私の環境の場合なので、そこは御自分の環境に読み替えて下さい） &lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
書き込む文字列は引数&quot;t1&quot;で渡されていると推測。&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint linenums&quot;&gt;servo: t1 
    | file |
    file _ FileStream fileNamed: &#39;/home/o10yan/Scratch/servo&#39;.
    file nextPutAll: t1.
    file close.
    (Delay forMilliseconds: 10) wait
&lt;/pre&gt;&lt;br /&gt;
（注：上記&quot;file _&quot;は、Scratchでは&quot;file ←&quot;と表示される） &lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvkwJEUxJInDnQi5M6HYbNy5zmtGCab-3CJ0tfa8nTBhyYAsuWveVXXW6-uTg9dJiI0qxpQygls2yn0wuP-9gYlCDaFOHijPTS87f8XH2XVoJy7F4xWZ6Z4q5mOShMfSgHp5-tbhMKuTmk/s1600/2017-03-04--1488614927_476x216_scrot.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvkwJEUxJInDnQi5M6HYbNy5zmtGCab-3CJ0tfa8nTBhyYAsuWveVXXW6-uTg9dJiI0qxpQygls2yn0wuP-9gYlCDaFOHijPTS87f8XH2XVoJy7F4xWZ6Z4q5mOShMfSgHp5-tbhMKuTmk/s1600/2017-03-04--1488614927_476x216_scrot.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Scratch側の準備は以上で終了。&lt;br /&gt;
試しに動かしてみて、ファイルができているかを確認。&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwzb9LGrlmn9NXcvqu7X22aZpUZL_VJRuaLLYnui7U1-9wqJ1vFbg3R8CrRys8uxEtSaJKpEqplCnEng3BocQPfNbm8C_gcbvyYgscFsTJC8dC3zC51EkUe3Y6qvSrQcsWdg4r5bhJ3ZS3/s1600/2017-03-04--1488613485_261x132_scrot.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwzb9LGrlmn9NXcvqu7X22aZpUZL_VJRuaLLYnui7U1-9wqJ1vFbg3R8CrRys8uxEtSaJKpEqplCnEng3BocQPfNbm8C_gcbvyYgscFsTJC8dC3zC51EkUe3Y6qvSrQcsWdg4r5bhJ3ZS3/s1600/2017-03-04--1488613485_261x132_scrot.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMuI97dGnFgxwFSt824fMJwFtJlB_GS9TibOOFm95WBlb5v3aTPHgyiB2D7zX54tcDRSd4NUhsOWMzdl6Q3fpGTwdIxsEQvAH3ITZa4E_oKTibYf6zRl0qzgxELDwfeTzAu7HDF4Dj9cbV/s1600/2017-03-04--1488613397_771x352_scrot.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;182&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMuI97dGnFgxwFSt824fMJwFtJlB_GS9TibOOFm95WBlb5v3aTPHgyiB2D7zX54tcDRSd4NUhsOWMzdl6Q3fpGTwdIxsEQvAH3ITZa4E_oKTibYf6zRl0qzgxELDwfeTzAu7HDF4Dj9cbV/s400/2017-03-04--1488613397_771x352_scrot.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
手順③で以下のように、ファイル監視のシェルスクリプトを作成。&lt;br /&gt;
ファイルの更新監視用に&quot;inotifywait&quot;を使うので、&lt;span style=&quot;color: blue;&quot;&gt;&lt;b&gt;予め&quot;inotify-tools&quot;をインストールしておく。&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
先ずは、監視用のファイルが存在するかを確認して、無ければ作っておく。 &lt;br /&gt;
&quot;inotifywait&quot;で指定のファイルに更新があるかを監視し、更新があった場合、&lt;br /&gt;
ファイルの内容を変数（text_line）に読み込んで、それを&quot;/dev/servoblaster&quot;へ送る。&lt;br /&gt;
ファイルに文字列が残ってしまうと気持ち悪いので、空白を書き込んでおく。&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-bash linenums&quot;&gt;#!/bin/bash

if [ ! -e /home/o10yan/Scratch/servo ]; then
    touch /home/o10yan/Scratch/servo
fi

while inotifywait -e modify /home/o10yan/Scratch/servo; do
    text_line=$(cat /home/o10yan/Scratch/servo)

    if [ -n &#39;$text_line&#39; ]; then
         echo &#39;&#39; &amp;gt; /home//o10yan/Scratch/servo
         echo $text_line &amp;gt; /dev/servoblaster
    fi
done
&lt;/pre&gt;&lt;br /&gt;
出来上がったシェルスクリプトを実行し、監視状態になることを確認し、&lt;br /&gt;
Scratchのブロックを動かす。&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAYbtK1ryqnGSq0twZqH-zuZZnOU0ouRgrO3k2ZZuLDY6pMvj5iU9PRB1OC-EfKj6ZoXz2eNJIbVpzKfVrgDFGPXa5J59x6Xx8a7DtIDdf0Ld0By7S6hNk8JmvZqqZSsUtMxWdu4sqXVNU/s1600/2017-03-04--1488612359_502x97_scrot.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAYbtK1ryqnGSq0twZqH-zuZZnOU0ouRgrO3k2ZZuLDY6pMvj5iU9PRB1OC-EfKj6ZoXz2eNJIbVpzKfVrgDFGPXa5J59x6Xx8a7DtIDdf0Ld0By7S6hNk8JmvZqqZSsUtMxWdu4sqXVNU/s1600/2017-03-04--1488612359_502x97_scrot.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiePKCjVjpcoSg5lVvha9uS3rMbx-6Th8AASDEPRnak1y103nPSBKZMpQccTDKwDF2A8_CK1_EknlUy2eqNThOtHtG0Vzu2KxqbSpoTH4KjS5mMzkPUwE228kpLzp9JiK22k7ZnYN-gwvT4/s1600/2017-03-04--1488614206_510x154_scrot.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiePKCjVjpcoSg5lVvha9uS3rMbx-6Th8AASDEPRnak1y103nPSBKZMpQccTDKwDF2A8_CK1_EknlUy2eqNThOtHtG0Vzu2KxqbSpoTH4KjS5mMzkPUwE228kpLzp9JiK22k7ZnYN-gwvT4/s1600/2017-03-04--1488614206_510x154_scrot.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
今回は、ServoBlasterを動かすための改造を行ったが、次回はLinuxコマンドを&lt;br /&gt;
送るような改造を行う。&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;color: blue;&quot;&gt;&lt;b&gt;※お願い※ &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: blue;&quot;&gt;&lt;b&gt;私は、Smalltalkについて全然分かっていないので、コピペ主体で改造してます。&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: blue;&quot;&gt;&lt;b&gt;Smalltalkに詳しい方で、「ここは間違っている」「こうした方が良い」と言う&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: blue;&quot;&gt;&lt;b&gt;指摘がありましたら、コメントを頂けると有難いです。&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: blue;&quot;&gt;&lt;b&gt;よろしくお願いします。 &lt;/b&gt;&lt;/span&gt;</content><link rel='replies' type='application/atom+xml' href='http://aoo10yan.blogspot.com/feeds/1817638892044456989/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://aoo10yan.blogspot.com/2017/03/scratch-14servoblaster.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7359781935835547652/posts/default/1817638892044456989'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7359781935835547652/posts/default/1817638892044456989'/><link rel='alternate' type='text/html' href='http://aoo10yan.blogspot.com/2017/03/scratch-14servoblaster.html' title='Scratch 1.4からServoBlasterを使う'/><author><name>AO_o10yan</name><uri>http://www.blogger.com/profile/00449541977510719198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrM3-Oo85V08_DgAZhY5omdxrrGFFA2HUG0S_p0uOgOZB0xDCRE4SujRFDT7awPJ4gflbKY3uvXlrMdlpLIggIA7_-nb0sDcR_cbydnZC7wu_6XqvWnxCqEOAqIPzR4l6wKStz17bgbDrS/s72-c/2017-03-04--1488612179_598x402_scrot.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7359781935835547652.post-1668729792159926455</id><published>2016-09-18T22:18:00.000+09:00</published><updated>2020-03-07T16:06:23.248+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="arch"/><category scheme="http://www.blogger.com/atom/ns#" term="gtkdialog"/><category scheme="http://www.blogger.com/atom/ns#" term="linux"/><category scheme="http://www.blogger.com/atom/ns#" term="quadruped"/><category scheme="http://www.blogger.com/atom/ns#" term="raspberry pi"/><category scheme="http://www.blogger.com/atom/ns#" term="robot"/><category scheme="http://www.blogger.com/atom/ns#" term="servoblaster"/><title type='text'>再修正「簡易ポーズエディタ」</title><content type='html'>&lt;a href=&quot;http://aoo10yan.blogspot.jp/2016/06/blog-post.html&quot; target=&quot;_blank&quot;&gt;修正「簡易ポーズエディタ」 &lt;/a&gt;で作ったスクリプトの&lt;span style=&quot;color: red;&quot;&gt;&lt;b&gt;再修正&lt;/b&gt;&lt;/span&gt;。&lt;br /&gt;
例によって、&lt;span style=&quot;color: red;&quot;&gt;&lt;b&gt;上部のボタンは意味なし 。&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
原点に対する補正値を入れられるようにした。&lt;br /&gt;
起動時に、原点復帰を行う。&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-bash linenums&quot;&gt;#!/bin/bash

export test00=&#39;
echo $USER
&#39;
export SERVO0=&#39;50&#39;
export SERVO1=&#39;50&#39;
export SERVO2=&#39;50&#39;
export SERVO3=&#39;50&#39;
export SERVO4=&#39;50&#39;
export SERVO5=&#39;50&#39;
export SERVO6=&#39;50&#39;
export SERVO7=&#39;50&#39;

#原点に対する補正値の設定 
export ADJUST0=&#39;4&#39;
export ADJUST1=&#39;3&#39;
export ADJUST2=&#39;-3&#39;
export ADJUST3=&#39;5&#39;
export ADJUST4=&#39;-4&#39;
export ADJUST5=&#39;-3&#39;
export ADJUST6=&#39;1&#39;
export ADJUST7=&#39;-3&#39;

for((i = 0; i &amp;lt;= 7; i++)); do
    echo $i=$((SERVO$i + ADJUST$i))% &amp;gt; /dev/servoblaster
done

export MAIN_DIALOG=&#39;
  &amp;lt;window&amp;gt;
    &amp;lt;vbox&amp;gt;
      &amp;lt;hbox&amp;gt;
        &amp;lt;vbox&amp;gt;
          &amp;lt;hbox&amp;gt;
            &amp;lt;frame サーボ5(%)&amp;gt;
              &amp;lt;vscale height-request=&quot;200&quot; range-min=&quot;10&quot; range-max=&quot;90&quot; range-step=&quot;1&quot;&amp;gt;
                &amp;lt;default&amp;gt;50&amp;lt;/default&amp;gt;
                &amp;lt;variable&amp;gt;SERVO5&amp;lt;/variable&amp;gt;
                &amp;lt;action&amp;gt;bash -c &quot;echo 5=&quot;$((SERVO5 + ADJUST5))&quot;% &amp;gt; /dev/servoblaster&quot;&amp;lt;/action&amp;gt;
                &amp;lt;action type=&quot;refresh&quot;&amp;gt;TEXT5&amp;lt;/action&amp;gt;
              &amp;lt;/vscale&amp;gt;
            &amp;lt;/frame&amp;gt;
            &amp;lt;frame サーボ4(%)&amp;gt;
              &amp;lt;vscale height-request=&quot;200&quot; range-min=&quot;10&quot; range-max=&quot;90&quot; range-step=&quot;1&quot;&amp;gt;
                &amp;lt;default&amp;gt;50&amp;lt;/default&amp;gt;
                &amp;lt;variable&amp;gt;SERVO4&amp;lt;/variable&amp;gt;
                &amp;lt;action&amp;gt;bash -c &quot;echo 4=&quot;$((SERVO4 + ADJUST4))&quot;% &amp;gt; /dev/servoblaster&quot;&amp;lt;/action&amp;gt;
                &amp;lt;action type=&quot;refresh&quot;&amp;gt;TEXT4&amp;lt;/action&amp;gt;
              &amp;lt;/vscale&amp;gt;
            &amp;lt;/frame&amp;gt;
          &amp;lt;/hbox&amp;gt;
          &amp;lt;hbox&amp;gt;
            &amp;lt;frame サーボ7(%)&amp;gt;
              &amp;lt;vscale height-request=&quot;200&quot; range-min=&quot;10&quot; range-max=&quot;90&quot; range-step=&quot;1&quot; inverted=&quot;true&quot;&amp;gt;
                &amp;lt;default&amp;gt;50&amp;lt;/default&amp;gt;
                &amp;lt;variable&amp;gt;SERVO7&amp;lt;/variable&amp;gt;
                &amp;lt;action&amp;gt;bash -c &quot;echo 7=&quot;$((SERVO7 + ADJUST7))&quot;% &amp;gt; /dev/servoblaster&quot;&amp;lt;/action&amp;gt;
                &amp;lt;action type=&quot;refresh&quot;&amp;gt;TEXT7&amp;lt;/action&amp;gt;
              &amp;lt;/vscale&amp;gt;
            &amp;lt;/frame&amp;gt;
            &amp;lt;frame サーボ6(%)&amp;gt;
              &amp;lt;vscale height-request=&quot;200&quot; range-min=&quot;10&quot; range-max=&quot;90&quot; range-step=&quot;1&quot;&amp;gt;
                &amp;lt;default&amp;gt;50&amp;lt;/default&amp;gt;
                &amp;lt;variable&amp;gt;SERVO6&amp;lt;/variable&amp;gt;
                &amp;lt;action&amp;gt;bash -c &quot;echo 6=&quot;$((SERVO6 + ADJUST8))&quot;% &amp;gt; /dev/servoblaster&quot;&amp;lt;/action&amp;gt;
                &amp;lt;action type=&quot;refresh&quot;&amp;gt;TEXT6&amp;lt;/action&amp;gt;
              &amp;lt;/vscale&amp;gt;
            &amp;lt;/frame&amp;gt;
          &amp;lt;/hbox&amp;gt;
        &amp;lt;/vbox&amp;gt;

        &amp;lt;vbox&amp;gt;
          &amp;lt;hbox&amp;gt;
            &amp;lt;button&amp;gt;
              &amp;lt;label&amp;gt;ボタン 1&amp;lt;/label&amp;gt;
              &amp;lt;action&amp;gt;echo $LANG&amp;lt;/action&amp;gt;
            &amp;lt;/button&amp;gt;
            &amp;lt;vbox&amp;gt;
              &amp;lt;button width-request=&quot;110&quot;&amp;gt;
                &amp;lt;label&amp;gt;前進&amp;lt;/label&amp;gt;
                &amp;lt;action&amp;gt;bash -c &quot;$test00&quot;&amp;lt;/action&amp;gt;
              &amp;lt;/button&amp;gt;
              &amp;lt;button&amp;gt;
                &amp;lt;label&amp;gt;後退&amp;lt;/label&amp;gt;
              &amp;lt;/button&amp;gt;
            &amp;lt;/vbox&amp;gt;
            &amp;lt;button&amp;gt;
              &amp;lt;label&amp;gt;ボタン 4&amp;lt;/label&amp;gt;
            &amp;lt;/button&amp;gt;
          &amp;lt;/hbox&amp;gt;
          &amp;lt;vbox&amp;gt;
            &amp;lt;frame&amp;gt;
              &amp;lt;text&amp;gt;
                &amp;lt;variable&amp;gt;TEXT0&amp;lt;/variable&amp;gt;
                &amp;lt;input&amp;gt;echo &quot;echo 0=&quot;$SERVO0&quot;% &amp;gt; /dev/servoblaster&quot;&amp;lt;/input&amp;gt;
              &amp;lt;/text&amp;gt;
              &amp;lt;text&amp;gt;
                &amp;lt;variable&amp;gt;TEXT1&amp;lt;/variable&amp;gt;
                &amp;lt;input&amp;gt;echo &quot;echo 1=&quot;$SERVO1&quot;% &amp;gt; /dev/servoblaster&quot;&amp;lt;/input&amp;gt;
              &amp;lt;/text&amp;gt;
              &amp;lt;text&amp;gt;
                &amp;lt;variable&amp;gt;TEXT2&amp;lt;/variable&amp;gt;
                &amp;lt;input&amp;gt;echo &quot;echo 2=&quot;$SERVO2&quot;% &amp;gt; /dev/servoblaster&quot;&amp;lt;/input&amp;gt;
              &amp;lt;/text&amp;gt;
              &amp;lt;text&amp;gt;
                &amp;lt;variable&amp;gt;TEXT3&amp;lt;/variable&amp;gt;
                &amp;lt;input&amp;gt;echo &quot;echo 3=&quot;$SERVO3&quot;% &amp;gt; /dev/servoblaster&quot;&amp;lt;/input&amp;gt;
              &amp;lt;/text&amp;gt;
              &amp;lt;text&amp;gt;
                &amp;lt;variable&amp;gt;TEXT4&amp;lt;/variable&amp;gt;
               &amp;lt;input&amp;gt;echo &quot;echo 4=&quot;$SERVO4&quot;% &amp;gt; /dev/servoblaster&quot;&amp;lt;/input&amp;gt;
              &amp;lt;/text&amp;gt;
              &amp;lt;text&amp;gt;
                &amp;lt;variable&amp;gt;TEXT5&amp;lt;/variable&amp;gt;
                &amp;lt;input&amp;gt;echo &quot;echo 5=&quot;$SERVO5&quot;% &amp;gt; /dev/servoblaster&quot;&amp;lt;/input&amp;gt;
              &amp;lt;/text&amp;gt;
              &amp;lt;text&amp;gt;
                &amp;lt;variable&amp;gt;TEXT6&amp;lt;/variable&amp;gt;
                &amp;lt;input&amp;gt;echo &quot;echo 6=&quot;$SERVO6&quot;% &amp;gt; /dev/servoblaster&quot;&amp;lt;/input&amp;gt;
              &amp;lt;/text&amp;gt;
              &amp;lt;text&amp;gt;
                &amp;lt;variable&amp;gt;TEXT7&amp;lt;/variable&amp;gt;
                &amp;lt;input&amp;gt;echo &quot;echo 7=&quot;$SERVO7&quot;% &amp;gt; /dev/servoblaster&quot;&amp;lt;/input&amp;gt;
              &amp;lt;/text&amp;gt;
            &amp;lt;/frame&amp;gt;
          &amp;lt;/vbox&amp;gt;
          &amp;lt;entry&amp;gt;
            &amp;lt;variable&amp;gt;FILE0&amp;lt;/variable&amp;gt;
            &amp;lt;default&amp;gt;&quot;./temp.txt&quot;&amp;lt;/default&amp;gt;
          &amp;lt;/entry&amp;gt;
          &amp;lt;button&amp;gt;
            &amp;lt;label&amp;gt;新規作成&amp;lt;/label&amp;gt;
            &amp;lt;action&amp;gt;echo &quot;#!/bin/bash&quot; &amp;gt; $FILE0&amp;lt;/action&amp;gt;
            &amp;lt;action&amp;gt;echo &quot;&quot; &amp;gt;&amp;gt; $FILE0&amp;lt;/action&amp;gt;
            &amp;lt;action&amp;gt;echo &quot;echo 0=&quot;$((SERVO0 + ADJUST0))&quot;% &amp;gt; /dev/servoblaster&quot; &amp;gt;&amp;gt; $FILE0&amp;lt;/action&amp;gt;
            &amp;lt;action&amp;gt;echo &quot;echo 1=&quot;$((SERVO1 + ADJUST1))&quot;% &amp;gt; /dev/servoblaster&quot; &amp;gt;&amp;gt; $FILE0&amp;lt;/action&amp;gt;
            &amp;lt;action&amp;gt;echo &quot;echo 2=&quot;$((SERVO2 + ADJUST2))&quot;% &amp;gt; /dev/servoblaster&quot; &amp;gt;&amp;gt; $FILE0&amp;lt;/action&amp;gt;
            &amp;lt;action&amp;gt;echo &quot;echo 3=&quot;$((SERVO3 + ADJUST3))&quot;% &amp;gt; /dev/servoblaster&quot; &amp;gt;&amp;gt; $FILE0&amp;lt;/action&amp;gt;
            &amp;lt;action&amp;gt;echo &quot;echo 4=&quot;$((SERVO4 + ADJUST4))&quot;% &amp;gt; /dev/servoblaster&quot; &amp;gt;&amp;gt; $FILE0&amp;lt;/action&amp;gt;
            &amp;lt;action&amp;gt;echo &quot;echo 5=&quot;$((SERVO5 + ADJUST5))&quot;% &amp;gt; /dev/servoblaster&quot; &amp;gt;&amp;gt; $FILE0&amp;lt;/action&amp;gt;
            &amp;lt;action&amp;gt;echo &quot;echo 6=&quot;$((SERVO6 + ADJUST6))&quot;% &amp;gt; /dev/servoblaster&quot; &amp;gt;&amp;gt; $FILE0&amp;lt;/action&amp;gt;
            &amp;lt;action&amp;gt;echo &quot;echo 7=&quot;$((SERVO7 + ADJUST7))&quot;% &amp;gt; /dev/servoblaster&quot; &amp;gt;&amp;gt; $FILE0&amp;lt;/action&amp;gt;
          &amp;lt;/button&amp;gt;
          &amp;lt;button&amp;gt;
            &amp;lt;label&amp;gt;ポーズ追加&amp;lt;/label&amp;gt;
            &amp;lt;action&amp;gt;echo &quot;&quot; &amp;gt;&amp;gt; $FILE0&amp;lt;/action&amp;gt;
            &amp;lt;action&amp;gt;echo &quot;sleep 1&quot; &amp;gt;&amp;gt; $FILE0&amp;lt;/action&amp;gt;
            &amp;lt;action&amp;gt;echo &quot;&quot; &amp;gt;&amp;gt; $FILE0&amp;lt;/action&amp;gt;
            &amp;lt;action&amp;gt;echo &quot;echo 0=&quot;$((SERVO0 + ADJUST0))&quot;% &amp;gt; /dev/servoblaster&quot; &amp;gt;&amp;gt; $FILE0&amp;lt;/action&amp;gt;
            &amp;lt;action&amp;gt;echo &quot;echo 1=&quot;$((SERVO1 + ADJUST1))&quot;% &amp;gt; /dev/servoblaster&quot; &amp;gt;&amp;gt; $FILE0&amp;lt;/action&amp;gt;
            &amp;lt;action&amp;gt;echo &quot;echo 2=&quot;$((SERVO2 + ADJUST2))&quot;% &amp;gt; /dev/servoblaster&quot; &amp;gt;&amp;gt; $FILE0&amp;lt;/action&amp;gt;
            &amp;lt;action&amp;gt;echo &quot;echo 3=&quot;$((SERVO3 + ADJUST3))&quot;% &amp;gt; /dev/servoblaster&quot; &amp;gt;&amp;gt; $FILE0&amp;lt;/action&amp;gt;
            &amp;lt;action&amp;gt;echo &quot;echo 4=&quot;$((SERVO4 + ADJUST4))&quot;% &amp;gt; /dev/servoblaster&quot; &amp;gt;&amp;gt; $FILE0&amp;lt;/action&amp;gt;
            &amp;lt;action&amp;gt;echo &quot;echo 5=&quot;$((SERVO5 + ADJUST5))&quot;% &amp;gt; /dev/servoblaster&quot; &amp;gt;&amp;gt; $FILE0&amp;lt;/action&amp;gt;
            &amp;lt;action&amp;gt;echo &quot;echo 6=&quot;$((SERVO6 + ADJUST6))&quot;% &amp;gt; /dev/servoblaster&quot; &amp;gt;&amp;gt; $FILE0&amp;lt;/action&amp;gt;
            &amp;lt;action&amp;gt;echo &quot;echo 7=&quot;$((SERVO7 + ADJUST7))&quot;% &amp;gt; /dev/servoblaster&quot; &amp;gt;&amp;gt; $FILE0&amp;lt;/action&amp;gt;
          &amp;lt;/button&amp;gt;
        &amp;lt;/vbox&amp;gt;

        &amp;lt;vbox&amp;gt;
          &amp;lt;hbox&amp;gt;
            &amp;lt;frame サーボ0(%)&amp;gt;
              &amp;lt;vscale height-request=&quot;200&quot; range-min=&quot;10&quot; range-max=&quot;90&quot; range-step=&quot;1&quot; inverted=&quot;true&quot;&amp;gt;
                &amp;lt;default&amp;gt;50&amp;lt;/default&amp;gt;
                &amp;lt;variable&amp;gt;SERVO0&amp;lt;/variable&amp;gt;
                &amp;lt;action&amp;gt;bash -c &quot;echo 0=&quot;$((SERVO0 + ADJUST0))&quot;% &amp;gt; /dev/servoblaster&quot;&amp;lt;/action&amp;gt;
                &amp;lt;action type=&quot;refresh&quot;&amp;gt;TEXT0&amp;lt;/action&amp;gt;
              &amp;lt;/vscale&amp;gt;
            &amp;lt;/frame&amp;gt;
            &amp;lt;frame サーボ1(%)&amp;gt;
              &amp;lt;vscale height-request=&quot;200&quot; range-min=&quot;10&quot; range-max=&quot;90&quot; range-step=&quot;1&quot; inverted=&quot;true&quot;&amp;gt;
                &amp;lt;default&amp;gt;50&amp;lt;/default&amp;gt;
                &amp;lt;variable&amp;gt;SERVO1&amp;lt;/variable&amp;gt;
                &amp;lt;action&amp;gt;bash -c &quot;echo 1=&quot;$((SERVO1 + ADJUST1))&quot;% &amp;gt; /dev/servoblaster&quot;&amp;lt;/action&amp;gt;
                &amp;lt;action type=&quot;refresh&quot;&amp;gt;TEXT1&amp;lt;/action&amp;gt;
              &amp;lt;/vscale&amp;gt;
            &amp;lt;/frame&amp;gt;
          &amp;lt;/hbox&amp;gt;
          &amp;lt;hbox&amp;gt;
            &amp;lt;frame サーボ2(%)&amp;gt;
              &amp;lt;vscale height-request=&quot;200&quot; range-min=&quot;10&quot; range-max=&quot;90&quot; range-step=&quot;1&quot; inverted=&quot;true&quot;&amp;gt;
                &amp;lt;default&amp;gt;50&amp;lt;/default&amp;gt;
                &amp;lt;variable&amp;gt;SERVO2&amp;lt;/variable&amp;gt;
                &amp;lt;action&amp;gt;bash -c &quot;echo 2=&quot;$((SERVO2 + ADJUST2))&quot;% &amp;gt; /dev/servoblaster&quot;&amp;lt;/action&amp;gt;
                &amp;lt;action type=&quot;refresh&quot;&amp;gt;TEXT2&amp;lt;/action&amp;gt;
              &amp;lt;/vscale&amp;gt;
            &amp;lt;/frame&amp;gt;
            &amp;lt;frame サーボ3(%)&amp;gt;
              &amp;lt;vscale height-request=&quot;200&quot; range-min=&quot;10&quot; range-max=&quot;90&quot; range-step=&quot;1&quot;&amp;gt;
                &amp;lt;default&amp;gt;50&amp;lt;/default&amp;gt;
                &amp;lt;variable&amp;gt;SERVO3&amp;lt;/variable&amp;gt;
                &amp;lt;action&amp;gt;bash -c &quot;echo 3=&quot;$((SERVO3 + ADJUST3))&quot;% &amp;gt; /dev/servoblaster&quot;&amp;lt;/action&amp;gt;
                &amp;lt;action type=&quot;refresh&quot;&amp;gt;TEXT3&amp;lt;/action&amp;gt;
              &amp;lt;/vscale&amp;gt;
            &amp;lt;/frame&amp;gt;
          &amp;lt;/hbox&amp;gt;
        &amp;lt;/vbox&amp;gt;
      &amp;lt;/hbox&amp;gt;
    &amp;lt;/vbox&amp;gt;
  &amp;lt;/window&amp;gt;
&#39;

gtkdialog -p MAIN_DIALOG -c 
&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://aoo10yan.blogspot.com/feeds/1668729792159926455/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://aoo10yan.blogspot.com/2016/09/blog-post.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7359781935835547652/posts/default/1668729792159926455'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7359781935835547652/posts/default/1668729792159926455'/><link rel='alternate' type='text/html' href='http://aoo10yan.blogspot.com/2016/09/blog-post.html' title='再修正「簡易ポーズエディタ」'/><author><name>AO_o10yan</name><uri>http://www.blogger.com/profile/00449541977510719198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7359781935835547652.post-2360454780003081697</id><published>2016-08-16T16:37:00.001+09:00</published><updated>2020-03-07T16:08:58.751+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="arch"/><category scheme="http://www.blogger.com/atom/ns#" term="gtkdialog"/><category scheme="http://www.blogger.com/atom/ns#" term="linux"/><title type='text'>ワークスペース毎に動くタイリング・シェルスクリプト</title><content type='html'>&lt;a href=&quot;http://aoo10yan.blogspot.jp/2016/07/gtkdialogopenbox.html&quot; target=&quot;_blank&quot;&gt;前回&lt;/a&gt;作成したシェルスクリプトを、ワークスペース毎に操作できるようにする&lt;span style=&quot;color: red;&quot;&gt;&lt;b&gt;実験&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiiJ0iIVo4c4jkldsWTtr0UECbgJNn4-cg32bdt1t8QY2RaHDqhhNcpFRyWcP97s5KIXn5hytX6y78WhH_hLF6hpFVDNmrz59yMxb83iDBeaXnxAEvwPboyOwWnfq13SPnhXubY24BSt5cL/s1600/2016-08-16--1471329726_196x73_scrot.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiiJ0iIVo4c4jkldsWTtr0UECbgJNn4-cg32bdt1t8QY2RaHDqhhNcpFRyWcP97s5KIXn5hytX6y78WhH_hLF6hpFVDNmrz59yMxb83iDBeaXnxAEvwPboyOwWnfq13SPnhXubY24BSt5cL/s1600/2016-08-16--1471329726_196x73_scrot.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEioDB6rBNSRjWF1TJgR4sTsrdeJjMKZ25Yo5p4cZCONMpDHjAd_2fmsdsFcgQPetbUCV2caQ7xCZjMoj-vXxja5MnryVBjBZDQb91eZCTa-4Y1XKN8cwqIcki3WVgHWBSKBm2bInlRAVCRc/s1600/2016-08-16--1471329753_195x73_scrot.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEioDB6rBNSRjWF1TJgR4sTsrdeJjMKZ25Yo5p4cZCONMpDHjAd_2fmsdsFcgQPetbUCV2caQ7xCZjMoj-vXxja5MnryVBjBZDQb91eZCTa-4Y1XKN8cwqIcki3WVgHWBSKBm2bInlRAVCRc/s1600/2016-08-16--1471329753_195x73_scrot.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;iframe allowfullscreen=&quot;&quot; class=&quot;YOUTUBE-iframe-video&quot; data-thumbnail-src=&quot;https://i.ytimg.com/vi/Pv8vx4Q9dhA/0.jpg&quot; frameborder=&quot;0&quot; height=&quot;266&quot; src=&quot;https://www.youtube.com/embed/Pv8vx4Q9dhA?feature=player_embedded&quot; width=&quot;320&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;br /&gt;
WmCtrlGtk(0)とWmCtrlGtk(1)で、それぞれワークスペース0とワークスペース1を別個に操作する。&lt;br /&gt;
（その分、シェルスクリプトから保存するファイルが増えてます。） &lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-bash linenums&quot;&gt;#!/bin/bash

PRE_IFS=$IFS
IFS=$&#39;\n&#39;

top_panel_h=0
bottom_panel_h=26
title_h=30
disp_width=$(xwininfo -root | grep &#39;Width&#39; | cut -f2 -d &#39;:&#39;)
disp_height=$(xwininfo -root | grep &#39;Height&#39; | cut -f2 -d &#39;:&#39;)
export current_ws=$(xprop -root -notype _NET_CURRENT_DESKTOP | cut -b 24)

if [ ! $(wmctrl -l | grep &quot;WmCtrlGtk(&quot;$current_ws&quot;)&quot;) ]; then
    export MAIN_DIALOG$current_ws=&#39;
    &amp;lt;window title=&quot;WmCtrlGtk(&#39;$current_ws&#39;)&quot;&amp;gt;
        &amp;lt;hbox&amp;gt;
            &amp;lt;button&amp;gt;
                &amp;lt;label&amp;gt;h&amp;lt;/label&amp;gt;
                &amp;lt;action&amp;gt;&#39;$0&#39; h 200&amp;lt;/action&amp;gt;
            &amp;lt;/button&amp;gt;
            &amp;lt;button&amp;gt;
                &amp;lt;label&amp;gt;v&amp;lt;/label&amp;gt;
                &amp;lt;action&amp;gt;&#39;$0&#39; v 200&amp;lt;/action&amp;gt;
            &amp;lt;/button&amp;gt;
            &amp;lt;button&amp;gt;
                &amp;lt;label&amp;gt;r&amp;lt;/label&amp;gt;
                &amp;lt;action&amp;gt;&#39;$0&#39; r&amp;lt;/action&amp;gt;
            &amp;lt;/button&amp;gt;
            &amp;lt;button&amp;gt;
                &amp;lt;label&amp;gt;+100&amp;lt;/label&amp;gt;
                &amp;lt;action&amp;gt;&#39;$0&#39; 100&amp;lt;/action&amp;gt;
            &amp;lt;/button&amp;gt;
            &amp;lt;button&amp;gt;
                &amp;lt;label&amp;gt;-100&amp;lt;/label&amp;gt;
                &amp;lt;action&amp;gt;&#39;$0&#39; -100&amp;lt;/action&amp;gt;
            &amp;lt;/button&amp;gt;
        &amp;lt;/hbox&amp;gt;
    &amp;lt;/window&amp;gt;
    &#39;

    gtkdialog -p MAIN_DIALOG$current_ws -c
fi

rotate_flag=0
if [ $# -eq 1 ]; then
    if [ $1 = &#39;h&#39; -o $1 = &#39;v&#39; ]; then
        hv_flag=$1
        main_add=0
    elif [ $1 = &#39;r&#39; ]; then
        rotate_flag=1
    elif [ $1 -gt 0 -o $1 -lt 0 ]; then
        rotate_flag=2
    else
        hv_flag=&#39;h&#39;
    fi
elif [ $# -eq 2 ]; then
    hv_flag=$1
    main_add=$2
else
    exit 0
fi

temp_file=&#39;./wm-ctrl&#39;$current_ws&#39;.txt&#39;
if [ $rotate_flag -gt 0 ]; then
    hv_flag=$(sed -n 1p ./wm-ctrl${current_ws}.his | cut -f1 -d&#39;,&#39;)
    main_add=$(sed -n 1p ./wm-ctrl${current_ws}.his | cut -f2 -d&#39;,&#39;)
    if [ $rotate_flag -eq 1 ]; then
        temp_1=$(sed -n 2p ./wm-ctrl${current_ws}.his)
        sed -i &#39;$a &#39;$temp_1&#39;&#39; ./wm-ctrl${current_ws}.his
        sed -i 1,2d ./wm-ctrl${current_ws}.his
    else
        sed -i 1d ./wm-ctrl${current_ws}.his
        main_add=$((main_add + $1))
    fi
    sed -i &#39;s/_/ /g&#39; ./wm-ctrl${current_ws}.his
    temp_file=&#39;./wm-ctrl&#39;$current_ws&#39;.his&#39;
fi

wmctrl -l &amp;gt; wm-ctrl${current_ws}.txt
sed -i &#39;/WmCtrlGtk/d&#39; ./wm-ctrl${current_ws}.txt
txt_lines=$(wc $temp_file | sed &#39;s/^[ \t]*//&#39; | cut -f1 -d &quot; &quot;)
if [ $txt_lines -gt 0 ]; then
#    current_ws=$(xprop -root -notype _NET_CURRENT_DESKTOP | cut -b 24)
    #active_win=$(xprop -root -notype _NET_ACTIVE_WINDOW | cut -b 33-43)

    ws_windows=0
    for((i = 1; i &amp;lt;= $txt_lines; i++)); do
        ws_flag=$(sed -n $i&#39;p&#39; $temp_file | cut -b 12-13)
        if [ $ws_flag -eq $current_ws ]; then
            let ws_windows++
        fi
    done

    disp_width2=$((disp_width / 2))
    disp_height2=$(($(((disp_height - top_panel_h - bottom_panel_h) / 2)) - title_h))
    disp_width_main=$((disp_width2 + main_add))
    disp_height_main=$((disp_height2 + main_add))
    disp_width_sub=$((disp_width2 - main_add))
    disp_height_sub=$((disp_height2 - main_add))

    pos_width=$((disp_width / 2))
    pos_height=$(((disp_height - top_panel_h - bottom_panel_h) / 2))

    if [ $hv_flag = &#39;v&#39; ]; then
        x_pos=(0 0 $pos_width $pos_width)
        y_pos=($((0 + top_panel_h)) $((pos_height + top_panel_h + main_add)) \
              $((pos_height + top_panel_h+ main_add)) $((0 + top_panel_h)))
    else
        x_pos=(0 $((pos_width + main_add)) $((pos_width + main_add)) 0)
        y_pos=($((0 + top_panel_h)) $((0 + top_panel_h)) $((pos_height + top_panel_h)) \
              $((pos_height + top_panel_h)))
    fi

    case $ws_windows in
        1)
            temp_width=$disp_width
            temp_height=$((disp_height - top_panel_h - bottom_panel_h - title_h));; 
        [2-3])
            temp_width=$disp_width2
            temp_height=$((disp_height - top_panel_h - bottom_panel_h - title_h));;
        *)
            temp_width=$disp_width2
            temp_height=$disp_height2;;
    esac

    window_array=()
    n=0
    for((i = 1; i &amp;lt;= $txt_lines; i++)); do
        if [ $n -gt 3 ]; then
            n=0
        fi
        ws_flag=$(sed -n $i&#39;p&#39; $temp_file | cut -b 11-13)
        if [ $ws_flag -eq $current_ws ]; then
            win_id=$(sed -n $i&#39;p&#39; $temp_file | cut -b 1-10)
            if [ $rotate_flag -eq 0 ]; then
                if [ $n -eq 0 ]; then
                    echo $hv_flag&#39;,&#39;$main_add&#39;,&#39; &amp;gt; wm-ctrl${current_ws}.his
                    echo $win_id&#39;__&#39;$current_ws&#39;_&#39; &amp;gt;&amp;gt; wm-ctrl${current_ws}.his
                else
                    echo $win_id&#39;__&#39;$current_ws&#39;_&#39; &amp;gt;&amp;gt; wm-ctrl${current_ws}.his
                fi
            fi
            if [ $ws_windows -eq 2 ]; then
                if [ $n -eq 0 ]; then
                    if [ $hv_flag = &#39;v&#39; ]; then
                        temp_width=$disp_width
                        temp_height=$disp_height_main
                    else
                        temp_width=$disp_width_main
                    fi
                else
                    if [ $hv_flag = &#39;v&#39; ]; then
                        temp_width=$disp_width
                        temp_height=$disp_height_sub 
                    else
                        temp_width=$disp_width_sub
                        temp_height=$((disp_height - top_panel_h - bottom_panel_h - title_h))
                    fi
                fi
            fi            
            if [ $ws_windows -eq 3 ]; then
                if [ $n -eq 0 ]; then
                    if [ $hv_flag = &#39;v&#39; ]; then
                        temp_width=$disp_width
                        temp_height=$disp_height_main
                    else
                        temp_width=$disp_width_main
                    fi
                fi
            fi
            if [ $ws_windows -gt 2 -a $n -gt 0 ]; then
                if [ $hv_flag = &#39;v&#39; ]; then
                    temp_width=$disp_width2
                    temp_height=$disp_height_sub 
                else
                    temp_width=$disp_width_sub
                    temp_height=$disp_height2
                fi
            fi
            if [ $ws_windows -gt 3 -a $n -gt 0 ]; then
                x_pos=(0 $pos_width $pos_width 0)
                y_pos=($((0 + top_panel_h)) $((0 + top_panel_h)) $((pos_height + top_panel_h)) \
                      $((pos_height + top_panel_h)))
                temp_width=$disp_width2
                temp_height=$disp_height2
            fi
            window_array+=( $win_id&#39;,&#39;${x_pos[$n]}&#39;,&#39;${y_pos[$n]}&#39;,&#39;$temp_width&#39;,&#39;$temp_height )
            let n++
        fi
    done

    for par in ${window_array[@]}; do
        for((i = 1; i &amp;lt;= 5; i++)); do
            declare par$i=$(echo ${par} | cut -f$i -d &#39;,&#39;)
        done
        wmctrl -i -r $par1 -e 0,$par2,$par3,$par4,$par5
    done
fi

if [ $rotate_flag -gt 0 ]; then
    sed -i &#39;s/ /_/g&#39; ./wm-ctrl${current_ws}.his
    temp=$hv_flag&#39;,&#39;$main_add&#39;,&#39;
    sed -i &#39;1i &#39;$temp&#39;&#39; ./wm-ctrl${current_ws}.his
fi
&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://aoo10yan.blogspot.com/feeds/2360454780003081697/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://aoo10yan.blogspot.com/2016/08/blog-post.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7359781935835547652/posts/default/2360454780003081697'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7359781935835547652/posts/default/2360454780003081697'/><link rel='alternate' type='text/html' href='http://aoo10yan.blogspot.com/2016/08/blog-post.html' title='ワークスペース毎に動くタイリング・シェルスクリプト'/><author><name>AO_o10yan</name><uri>http://www.blogger.com/profile/00449541977510719198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiiJ0iIVo4c4jkldsWTtr0UECbgJNn4-cg32bdt1t8QY2RaHDqhhNcpFRyWcP97s5KIXn5hytX6y78WhH_hLF6hpFVDNmrz59yMxb83iDBeaXnxAEvwPboyOwWnfq13SPnhXubY24BSt5cL/s72-c/2016-08-16--1471329726_196x73_scrot.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7359781935835547652.post-4651055700349121022</id><published>2016-07-03T18:56:00.001+09:00</published><updated>2020-03-07T16:10:00.273+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="arch"/><category scheme="http://www.blogger.com/atom/ns#" term="gtkdialog"/><category scheme="http://www.blogger.com/atom/ns#" term="linux"/><title type='text'>GtkDialogでOpenboxウィンドウのタイリング</title><content type='html'>&lt;a href=&quot;http://aoo10yan.blogspot.jp/2016/06/wmctrl.html&quot; target=&quot;_blank&quot;&gt;前回&lt;/a&gt;、作成したシェルスクリプトをGtkDialogを使ってGUI操作できるようにする&lt;span style=&quot;color: red;&quot;&gt;&lt;b&gt;実験&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgc28NXDdhJFQGbDH0I3IJJcjS4og9dQFzR_6eETVb4kY-42pcRguD-teBnxj8FCH7WCUZLY-EEdMylZfhsX8L4So_5IAls9cjohb2kwb4DnLXUGg_MRgC2vOQNB7PjKYmJ0LtfpAAk1-q1/s1600/2016-07-03--1467538557_197x72_scrot.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgc28NXDdhJFQGbDH0I3IJJcjS4og9dQFzR_6eETVb4kY-42pcRguD-teBnxj8FCH7WCUZLY-EEdMylZfhsX8L4So_5IAls9cjohb2kwb4DnLXUGg_MRgC2vOQNB7PjKYmJ0LtfpAAk1-q1/s1600/2016-07-03--1467538557_197x72_scrot.png&quot; /&gt;&lt;/a&gt;&lt;iframe allowfullscreen=&quot;&quot; class=&quot;YOUTUBE-iframe-video&quot; data-thumbnail-src=&quot;https://i9.ytimg.com/vi/z0_zipgdxOw/default.jpg?sqp=CMi_47sF&amp;amp;rs=AOn4CLDJCx-73xNOKU6XjRRI0jbWedueiA&quot; frameborder=&quot;0&quot; height=&quot;266&quot; src=&quot;https://www.youtube.com/embed/z0_zipgdxOw?feature=player_embedded&quot; width=&quot;320&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;br /&gt;
※追記1（2016/07/09　21:00）※&lt;br /&gt;
一応、上部にパネルを表示している場合を想定。&lt;br /&gt;
top_panel_hで高さを指定する。&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-bash linenums&quot;&gt;#!/bin/bash

PRE_IFS=$IFS
IFS=$&#39;\n&#39;

top_panel_h=0
bottom_panel_h=26
title_h=30
disp_width=$(xwininfo -root | grep &#39;Width&#39; | cut -f2 -d &#39;:&#39;)
disp_height=$(xwininfo -root | grep &#39;Height&#39; | cut -f2 -d &#39;:&#39;)

if [ ! $(wmctrl -l | grep &quot;WmCtrlGtk&quot;) ]; then
    export MAIN_DIALOG=&#39;
    &amp;lt;window title=&quot;WmCtrlGtk&quot;&amp;gt;
        &amp;lt;hbox&amp;gt;
            &amp;lt;button&amp;gt;
                &amp;lt;label&amp;gt;h&amp;lt;/label&amp;gt;
                &amp;lt;action&amp;gt;&#39;$0&#39; h&amp;lt;/action&amp;gt;
            &amp;lt;/button&amp;gt;
            &amp;lt;button&amp;gt;
                &amp;lt;label&amp;gt;v&amp;lt;/label&amp;gt;
                &amp;lt;action&amp;gt;&#39;$0&#39; v&amp;lt;/action&amp;gt;
            &amp;lt;/button&amp;gt;
            &amp;lt;button&amp;gt;
                &amp;lt;label&amp;gt;r&amp;lt;/label&amp;gt;
                &amp;lt;action&amp;gt;&#39;$0&#39; r&amp;lt;/action&amp;gt;
            &amp;lt;/button&amp;gt;
            &amp;lt;button&amp;gt;
                &amp;lt;label&amp;gt;+100&amp;lt;/label&amp;gt;
                &amp;lt;action&amp;gt;&#39;$0&#39; 100&amp;lt;/action&amp;gt;
            &amp;lt;/button&amp;gt;
            &amp;lt;button&amp;gt;
                &amp;lt;label&amp;gt;-100&amp;lt;/label&amp;gt;
                &amp;lt;action&amp;gt;&#39;$0&#39; -100&amp;lt;/action&amp;gt;
            &amp;lt;/button&amp;gt;
        &amp;lt;/hbox&amp;gt;
    &amp;lt;/window&amp;gt;
    &#39;

    gtkdialog -p MAIN_DIALOG -c
fi

rotate_flag=0
if [ $# -eq 1 ]; then
    if [ $1 = &#39;h&#39; -o $1 = &#39;v&#39; ]; then
        hv_flag=$1
        main_add=0
    elif [ $1 = &#39;r&#39; ]; then
        rotate_flag=1
    elif [ $1 -gt 0 -o $1 -lt 0 ]; then
        rotate_flag=2
    else
        hv_flag=&#39;h&#39;
    fi
elif [ $# -eq 2 ]; then
    hv_flag=$1
    main_add=$2
else
    exit 0
fi

temp_file=&#39;./wm-ctrl.txt&#39;
if [ $rotate_flag -gt 0 ]; then
    hv_flag=$(sed -n 1p ./wm-ctrl.his | cut -f1 -d&#39;,&#39;)
    main_add=$(sed -n 1p ./wm-ctrl.his | cut -f2 -d&#39;,&#39;)
    if [ $rotate_flag -eq 1 ]; then
        temp_1=$(sed -n 2p ./wm-ctrl.his)
        sed -i &#39;$a &#39;$temp_1&#39;&#39; ./wm-ctrl.his
        sed -i 1,2d ./wm-ctrl.his
    else
        sed -i 1d ./wm-ctrl.his
        main_add=$((main_add + $1))
    fi
    sed -i &#39;s/_/ /g&#39; ./wm-ctrl.his
    temp_file=&#39;./wm-ctrl.his&#39;
fi

wmctrl -l &amp;gt; wm-ctrl.txt
sed -i &#39;/WmCtrlGtk/d&#39; ./wm-ctrl.txt
txt_lines=$(wc $temp_file | sed &#39;s/^[ \t]*//&#39; | cut -f1 -d &quot; &quot;)
if [ $txt_lines -gt 0 ]; then
    current_ws=$(xprop -root -notype _NET_CURRENT_DESKTOP | cut -b 24)
    #active_win=$(xprop -root -notype _NET_ACTIVE_WINDOW | cut -b 33-43)

    ws_windows=0
    for((i = 1; i &amp;lt;= $txt_lines; i++)); do
        ws_flag=$(sed -n $i&#39;p&#39; $temp_file | cut -b 12-13)
        if [ $ws_flag -eq $current_ws ]; then
            let ws_windows++
        fi
    done

    disp_width2=$((disp_width / 2))
    disp_height2=$(($(((disp_height - top_panel_h - bottom_panel_h) / 2)) - title_h))
    disp_width_main=$((disp_width2 + main_add))
    disp_height_main=$((disp_height2 + main_add))
    disp_width_sub=$((disp_width2 - main_add))
    disp_height_sub=$((disp_height2 - main_add))

    pos_width=$((disp_width / 2))
    pos_height=$(((disp_height - top_panel_h - bottom_panel_h) / 2))

    if [ $hv_flag = &#39;v&#39; ]; then
        x_pos=(0 0 $pos_width $pos_width)
        y_pos=($((0 + top_panel_h)) $((pos_height + top_panel_h + main_add)) \
              $((pos_height + top_panel_h+ main_add)) $((0 + top_panel_h)))
    else
        x_pos=(0 $((pos_width + main_add)) $((pos_width + main_add)) 0)
        y_pos=($((0 + top_panel_h)) $((0 + top_panel_h)) $((pos_height + top_panel_h)) \
              $((pos_height + top_panel_h)))
    fi

    case $ws_windows in
        1)
            temp_width=$disp_width
            temp_height=$((disp_height - top_panel_h - bottom_panel_h - title_h));; 
        [2-3])
            temp_width=$disp_width2
            temp_height=$((disp_height - top_panel_h - bottom_panel_h - title_h));;
        *)
            temp_width=$disp_width2
            temp_height=$disp_height2;;
    esac

    window_array=()
    n=0
    for((i = 1; i &amp;lt;= $txt_lines; i++)); do
        if [ $n -gt 3 ]; then
            n=0
        fi
        ws_flag=$(sed -n $i&#39;p&#39; $temp_file | cut -b 11-13)
        if [ $ws_flag -eq $current_ws ]; then
            win_id=$(sed -n $i&#39;p&#39; $temp_file | cut -b 1-10)
            if [ $rotate_flag -eq 0 ]; then
                if [ $n -eq 0 ]; then
                    echo $hv_flag&#39;,&#39;$main_add&#39;,&#39; &amp;gt; wm-ctrl.his
                    echo $win_id&#39;__&#39;$current_ws&#39;_&#39; &amp;gt;&amp;gt; wm-ctrl.his
                else
                    echo $win_id&#39;__&#39;$current_ws&#39;_&#39; &amp;gt;&amp;gt; wm-ctrl.his
                fi
            fi
            if [ $ws_windows -eq 2 ]; then
                if [ $n -eq 0 ]; then
                    if [ $hv_flag = &#39;v&#39; ]; then
                        temp_width=$disp_width
                        temp_height=$disp_height_main
                    else
                        temp_width=$disp_width_main
                    fi
                else
                    if [ $hv_flag = &#39;v&#39; ]; then
                        temp_width=$disp_width
                        temp_height=$disp_height_sub 
                    else
                        temp_width=$disp_width_sub
                        temp_height=$((disp_height - top_panel_h - bottom_panel_h - title_h))
                    fi
                fi
            fi            
            if [ $ws_windows -eq 3 ]; then
                if [ $n -eq 0 ]; then
                    if [ $hv_flag = &#39;v&#39; ]; then
                        temp_width=$disp_width
                        temp_height=$disp_height_main
                    else
                        temp_width=$disp_width_main
                    fi
                fi
            fi
            if [ $ws_windows -gt 2 -a $n -gt 0 ]; then
                if [ $hv_flag = &#39;v&#39; ]; then
                    temp_width=$disp_width2
                    temp_height=$disp_height_sub 
                else
                    temp_width=$disp_width_sub
                    temp_height=$disp_height2
                fi
            fi
            if [ $ws_windows -gt 3 -a $n -gt 0 ]; then
                x_pos=(0 $pos_width $pos_width 0)
                y_pos=($((0 + top_panel_h)) $((0 + top_panel_h)) $((pos_height + top_panel_h)) \
                      $((pos_height + top_panel_h)))
                temp_width=$disp_width2
                temp_height=$disp_height2
            fi
            window_array+=( $win_id&#39;,&#39;${x_pos[$n]}&#39;,&#39;${y_pos[$n]}&#39;,&#39;$temp_width&#39;,&#39;$temp_height )
            let n++
        fi
    done

    for par in ${window_array[@]}; do
        for((i = 1; i &amp;lt;= 5; i++)); do
            declare par$i=$(echo ${par} | cut -f$i -d &#39;,&#39;)
        done
        wmctrl -i -r $par1 -e 0,$par2,$par3,$par4,$par5
    done
fi

if [ $rotate_flag -gt 0 ]; then
    sed -i &#39;s/ /_/g&#39; ./wm-ctrl.his
    temp=$hv_flag&#39;,&#39;$main_add&#39;,&#39;
    sed -i &#39;1i &#39;$temp&#39;&#39; ./wm-ctrl.his
fi
&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://aoo10yan.blogspot.com/feeds/4651055700349121022/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://aoo10yan.blogspot.com/2016/07/gtkdialogopenbox.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7359781935835547652/posts/default/4651055700349121022'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7359781935835547652/posts/default/4651055700349121022'/><link rel='alternate' type='text/html' href='http://aoo10yan.blogspot.com/2016/07/gtkdialogopenbox.html' title='GtkDialogでOpenboxウィンドウのタイリング'/><author><name>AO_o10yan</name><uri>http://www.blogger.com/profile/00449541977510719198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgc28NXDdhJFQGbDH0I3IJJcjS4og9dQFzR_6eETVb4kY-42pcRguD-teBnxj8FCH7WCUZLY-EEdMylZfhsX8L4So_5IAls9cjohb2kwb4DnLXUGg_MRgC2vOQNB7PjKYmJ0LtfpAAk1-q1/s72-c/2016-07-03--1467538557_197x72_scrot.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7359781935835547652.post-1555540112585270899</id><published>2016-06-19T18:19:00.000+09:00</published><updated>2020-03-07T16:12:48.489+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="arch"/><category scheme="http://www.blogger.com/atom/ns#" term="linux"/><title type='text'>wmctrlでOpenboxウィンドウのタイリング</title><content type='html'>wmctrlを使ったシェルスクリプトでOpenboxのウィンドウを&lt;br /&gt;
タイリング操作してみる。&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;iframe allowfullscreen=&quot;&quot; class=&quot;YOUTUBE-iframe-video&quot; data-thumbnail-src=&quot;https://i.ytimg.com/vi/t9azVoyHZY4/0.jpg&quot; frameborder=&quot;0&quot; height=&quot;266&quot; src=&quot;https://www.youtube.com/embed/t9azVoyHZY4?feature=player_embedded&quot; width=&quot;320&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;br /&gt;
（録画にリソースをとられているので緩慢な動きですが、&lt;br /&gt;
実際は、、、。もう少しだけマシかな？）&lt;br /&gt;
&lt;br /&gt;
※一応スクリプトを載せますが、ググればもっと素晴らしいスクリプトが出てくるので、&lt;br /&gt;
興味のある方はそちらを見てくださいね。&lt;br /&gt;
→&lt;a href=&quot;https://bbs.archlinux.org/viewtopic.php?id=119020&quot; target=&quot;_blank&quot;&gt;https://bbs.archlinux.org/viewtopic.php?id=119020&lt;/a&gt; &lt;br /&gt;
尚、スクリプトには別途、wmctrl とxorg-apps のインストールが必要です※&lt;br /&gt;
&lt;br /&gt;
※追記1（2016/06/21　20:25）※&lt;br /&gt;
スクリプトの書式を変更。機能的な変化はなし。 &lt;br /&gt;
※追記2（2016/06/27　21:50）※&lt;br /&gt;
余分な処理を削除。機能的な変化なし。&lt;br /&gt;
※追記3（2016/06/28　22:30）※&lt;br /&gt;
メインウィンドウのローテーションを保持したままサイズ変更出きるようにした。&lt;br /&gt;
第一引数に数値（ピクセル単位）だけを指定すると、メインウィンドウのサイズが変更される。&lt;br /&gt;
プラスの数値で広く、マイナスの数値で狭くなる。&lt;br /&gt;
＜使い方＞&lt;br /&gt;
第一引数には、h、v、r及び数値の指定ができる。&lt;br /&gt;
h　　ウィンドウを横に並べる。第2引数に数値を指定すると、その数値の分だけメインウィンドウが広くなる。&lt;br /&gt;
v　　ウィンドウを縦に並べる。第2引数に数値を指定すると、その数値の分だけメインウィンドウが広くなる。&lt;br /&gt;
r　　メインウィンドウを入れ替える（ローテートする）。&lt;br /&gt;
数値　 メインウィンドウのサイズ変更。&lt;br /&gt;
（ウィンドウが4つ以上だと、メインの意味はなくなるので注意）&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-bash linenums&quot;&gt;#!/bin/bash

PRE_IFS=$IFS
IFS=$&#39;\n&#39;

panel_h=28
title_h=28
disp_width=$(xwininfo -root | grep &#39;Width&#39; | cut -f2 -d &#39;:&#39; | sed &#39;s/^[ \t]*//&#39;)
disp_height=$(xwininfo -root | grep &#39;Height&#39; | cut -f2 -d &#39;:&#39; | sed &#39;s/^[ \t]*//&#39;)

rotate_flag=0
if [ $# -eq 1 ]; then
    if [ $1 = &#39;h&#39; -o $1 = &#39;v&#39; ]; then
        hv_flag=$1
        main_add=0
    elif [ $1 = &#39;r&#39; ]; then
        rotate_flag=1
    elif [ $1 -gt 0 -o $1 -lt 0 ]; then
        rotate_flag=2
    else
        hv_flag=&#39;h&#39;
        #main_add=$1
    fi
elif [ $# -eq 2 ]; then
    hv_flag=$1
    main_add=$2
else
    hv_flag=&#39;h&#39;
    main_add=0
fi

temp_file=&#39;./wm-ctrl.txt&#39;
if [ $rotate_flag -gt 0 ]; then
    hv_flag=$(sed -n 1p ./wm-ctrl.his | cut -f1 -d&#39;,&#39;)
    main_add=$(sed -n 1p ./wm-ctrl.his | cut -f2 -d&#39;,&#39; | sed &#39;s/^[ \t]*//&#39;)
    if [ $rotate_flag -eq 1 ]; then
        temp_1=$(sed -n 2p ./wm-ctrl.his)
        sed -i &#39;$a &#39;$temp_1&#39;&#39; ./wm-ctrl.his
        sed -i 1,2d ./wm-ctrl.his
    else
        sed -i 1d ./wm-ctrl.his
        main_add=$((main_add + $1))
    fi
    sed -i &#39;s/_/ /g&#39; ./wm-ctrl.his
    temp_file=&#39;./wm-ctrl.his&#39;
fi

wmctrl -l &amp;gt; wm-ctrl.txt
txt_lines=$(wc $temp_file | sed &#39;s/^[ \t]*//&#39; | cut -f1 -d &quot; &quot;)
if [ $txt_lines -gt 0 ]; then
    current_ws=$(xprop -root -notype _NET_CURRENT_DESKTOP | cut -b 24)
    #active_win=$(xprop -root -notype _NET_ACTIVE_WINDOW | cut -b 33-43)

    ws_windows=0
    for((i = 1; i &amp;lt;= $txt_lines; i++)); do
        ws_flag=$(sed -n $i&#39;p&#39; $temp_file | cut -b 12-13)
        if [ $ws_flag -eq $current_ws ]; then
            let ws_windows++
        fi
    done

    disp_width2=$((disp_width / 2))
    disp_height2=$(($(((disp_height - panel_h) / 2)) - title_h))
    disp_width_main=$((disp_width2 + main_add))
    disp_height_main=$((disp_height2 + main_add))
    disp_width_sub=$((disp_width2 - main_add))
    disp_height_sub=$((disp_height2 - main_add))

    pos_width=$((disp_width / 2))
    pos_height=$(((disp_height - panel_h) / 2))

    if [ $hv_flag = &#39;v&#39; ]; then
        x_pos=(0 0 $pos_width $pos_width)
        y_pos=(0 $((pos_height + main_add)) $((pos_height + main_add)) 0)
    else
        x_pos=(0 $((pos_width + main_add)) $((pos_width + main_add)) 0)
        y_pos=(0 0 $pos_height $pos_height)
    fi

    case $ws_windows in
        1)
            temp_width=$disp_width
            temp_height=$((disp_height - panel_h - title_h));; 
        [2-3])
            temp_width=$disp_width2
            temp_height=$((disp_height - panel_h - title_h));;
        *)
            temp_width=$disp_width2
            temp_height=$disp_height2;;
    esac

    window_array=()
    n=0
    for((i = 1; i &amp;lt;= $txt_lines; i++)); do
        if [ $n -gt 3 ]; then
            n=0
        fi
        ws_flag=$(sed -n $i&#39;p&#39; $temp_file | cut -b 11-13 | sed &#39;s/^[ \t]*//&#39;)
        if [ $ws_flag -eq $current_ws ]; then
            win_id=$(sed -n $i&#39;p&#39; $temp_file | cut -b 1-10)
            if [ $rotate_flag -eq 0 ]; then
                if [ $n -eq 0 ]; then
                    echo $hv_flag&#39;,&#39;$main_add&#39;,&#39; &amp;gt; wm-ctrl.his
                    echo $win_id&#39;__&#39;$current_ws&#39;_&#39; &amp;gt;&amp;gt; wm-ctrl.his
                else
                    echo $win_id&#39;__&#39;$current_ws&#39;_&#39; &amp;gt;&amp;gt; wm-ctrl.his
                fi
            fi
            if [ $ws_windows -eq 2 ]; then
                if [ $n -eq 0 ]; then
                    if [ $hv_flag = &#39;v&#39; ]; then
                        temp_width=$disp_width
                        temp_height=$disp_height_main
                    else
                        temp_width=$disp_width_main
                    fi
                else
                    if [ $hv_flag = &#39;v&#39; ]; then
                        temp_width=$disp_width
                        temp_height=$disp_height_sub
                    else
                        temp_width=$disp_width_sub
                        temp_height=$((disp_height - panel_h - title_h))
                    fi
                fi
            fi            
            if [ $ws_windows -eq 3 ]; then
                if [ $n -eq 0 ]; then
                    if [ $hv_flag = &#39;v&#39; ]; then
                        temp_width=$disp_width
                        temp_height=$disp_height_main
                    else
                        temp_width=$disp_width_main
                    fi
                fi
            fi
            if [ $ws_windows -gt 2 -a $n -gt 0 ]; then
                if [ $hv_flag = &#39;v&#39; ]; then
                    temp_width=$disp_width2
                    temp_height=$disp_height_sub
                else
                    temp_width=$disp_width_sub
                    temp_height=$disp_height2
                fi
            fi
            if [ $ws_windows -gt 3 -a $n -gt 0 ]; then
                x_pos=(0 $pos_width $pos_width 0)
                y_pos=(0 0 $pos_height $pos_height)
                temp_width=$disp_width2
                temp_height=$disp_height2
            fi
            window_array+=( $win_id&#39;,&#39;${x_pos[$n]}&#39;,&#39;${y_pos[$n]}&#39;,&#39;$temp_width&#39;,&#39;$temp_height )
            let n++
        fi
    done

    for par in ${window_array[@]}; do
        for((i = 1; i &amp;lt;= 5; i++)); do
            declare par$i=$(echo ${par} | cut -f$i -d &#39;,&#39;)
        done
        wmctrl -i -r $par1 -e 0,$par2,$par3,$par4,$par5
    done
fi

if [ $rotate_flag -gt 0 ]; then
    sed -i &#39;s/ /_/g&#39; ./wm-ctrl.his
    temp=$hv_flag&#39;,&#39;$main_add&#39;,&#39;
    sed -i &#39;1i &#39;$temp&#39;&#39; ./wm-ctrl.his
fi
&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://aoo10yan.blogspot.com/feeds/1555540112585270899/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://aoo10yan.blogspot.com/2016/06/wmctrl.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7359781935835547652/posts/default/1555540112585270899'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7359781935835547652/posts/default/1555540112585270899'/><link rel='alternate' type='text/html' href='http://aoo10yan.blogspot.com/2016/06/wmctrl.html' title='wmctrlでOpenboxウィンドウのタイリング'/><author><name>AO_o10yan</name><uri>http://www.blogger.com/profile/00449541977510719198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img.youtube.com/vi/t9azVoyHZY4/default.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7359781935835547652.post-8568522444206532960</id><published>2016-06-05T15:21:00.000+09:00</published><updated>2020-03-07T16:14:39.653+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="arch"/><category scheme="http://www.blogger.com/atom/ns#" term="gtkdialog"/><category scheme="http://www.blogger.com/atom/ns#" term="linux"/><category scheme="http://www.blogger.com/atom/ns#" term="quadruped"/><category scheme="http://www.blogger.com/atom/ns#" term="raspberry pi"/><category scheme="http://www.blogger.com/atom/ns#" term="robot"/><category scheme="http://www.blogger.com/atom/ns#" term="servoblaster"/><title type='text'>修正「簡易ポーズエディタ」</title><content type='html'>&lt;a href=&quot;http://aoo10yan.blogspot.jp/2015/10/raspberry-pi-24.html&quot; target=&quot;_blank&quot;&gt;Raspberry Pi 2　4足歩行ロボット用「簡易ポーズエディタ」 &lt;/a&gt;で作ったスクリプトの修正。&lt;br /&gt;
例によって、&lt;span style=&quot;color: red;&quot;&gt;&lt;b&gt;上部のボタンは意味なし 。&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3fajraWK33bSVQyzvgfPzJwjmd81kQ5d81pXbIXVZvgIQb1yqYhstz-4wRtB9jqYQS7XX50WUJzsFjcvbFuTgiAuKZ1uMQDq9rmgcXIRKEhX7Xo-vixAQG2jBHMhfrMcNLrCHmm9F2hqm/s1600/2016-06-05--1465105262_644x509_scrot.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;315&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3fajraWK33bSVQyzvgfPzJwjmd81kQ5d81pXbIXVZvgIQb1yqYhstz-4wRtB9jqYQS7XX50WUJzsFjcvbFuTgiAuKZ1uMQDq9rmgcXIRKEhX7Xo-vixAQG2jBHMhfrMcNLrCHmm9F2hqm/s400/2016-06-05--1465105262_644x509_scrot.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
レイアウト修正と、ファイル「新規作成」の修正及び、「ポーズ追加」ボタンの付加。&lt;br /&gt;
&lt;br /&gt;
中央下の「新規作成」ボタンでスクリプトファイル（形式のテキストファイル)作成。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbaDhTwKI9e802lnF7SsV6TdOTQsZrthuCIh3X8xz4YBwuQKA60AVWQpfUE51TrUwPjIq-A6TnoZjuMpba7sZ3UNiHvaL1uCt02e06JWCJiosewcJEujYAM56aAd_uC1cHhzlrfdvUL6Sv/s1600/2016-06-05--1465105391_773x483_scrot.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;399&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbaDhTwKI9e802lnF7SsV6TdOTQsZrthuCIh3X8xz4YBwuQKA60AVWQpfUE51TrUwPjIq-A6TnoZjuMpba7sZ3UNiHvaL1uCt02e06JWCJiosewcJEujYAM56aAd_uC1cHhzlrfdvUL6Sv/s640/2016-06-05--1465105391_773x483_scrot.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
「ポーズ追加」ボタンで、次のポーズを追加。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEia6KWqizA9gLIj3NrB0GS868odOp-1neTvBSuJYKZXzOnh_qEoxAyS6GP7Fo27NT3W6Ca4YAYAH3fELsZHauDp21Ssza-ATF8eXDMsG6CSM9PwkENmAvrJF4UNyaCxJDZVtdlyiai6j-lG/s1600/2016-06-05--1465105479_771x621_scrot.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;515&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEia6KWqizA9gLIj3NrB0GS868odOp-1neTvBSuJYKZXzOnh_qEoxAyS6GP7Fo27NT3W6Ca4YAYAH3fELsZHauDp21Ssza-ATF8eXDMsG6CSM9PwkENmAvrJF4UNyaCxJDZVtdlyiai6j-lG/s640/2016-06-05--1465105479_771x621_scrot.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
テキストファイルなので、実行権限はなし。&lt;br /&gt;
動きの無いサーボモータに対しても同位置の指示が書き込みされている。&lt;br /&gt;
ポーズ間のスリープは1秒固定。&lt;br /&gt;
&lt;br /&gt;
実際には、上の修正をしながらシェルスクリプトとして手作業で仕上げて行く。&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-bash linenums&quot;&gt;#!/bin/bash

export test00=&#39;
echo $USER
&#39;
export SERVO0=&#39;50&#39;
export SERVO1=&#39;50&#39;
export SERVO2=&#39;50&#39;
export SERVO3=&#39;50&#39;
export SERVO4=&#39;50&#39;
export SERVO5=&#39;50&#39;
export SERVO6=&#39;50&#39;
export SERVO7=&#39;50&#39;

export MAIN_DIALOG=&#39;
  &amp;lt;window&amp;gt;
    &amp;lt;vbox&amp;gt;
      &amp;lt;hbox&amp;gt;
        &amp;lt;vbox&amp;gt;
          &amp;lt;hbox&amp;gt;
            &amp;lt;frame サーボ5(%)&amp;gt;
              &amp;lt;vscale height-request=&quot;200&quot; range-min=&quot;10&quot; range-max=&quot;90&quot; range-step=&quot;1&quot;&amp;gt;
                &amp;lt;default&amp;gt;50&amp;lt;/default&amp;gt;
                &amp;lt;variable&amp;gt;SERVO5&amp;lt;/variable&amp;gt;
                &amp;lt;action&amp;gt;bash -c &quot;echo 5=&quot;$SERVO5&quot;% &amp;gt; /dev/servoblaster&quot;&amp;lt;/action&amp;gt;
                &amp;lt;action type=&quot;refresh&quot;&amp;gt;TEXT5&amp;lt;/action&amp;gt;
              &amp;lt;/vscale&amp;gt;
            &amp;lt;/frame&amp;gt;
            &amp;lt;frame サーボ4(%)&amp;gt;
              &amp;lt;vscale height-request=&quot;200&quot; range-min=&quot;10&quot; range-max=&quot;90&quot; range-step=&quot;1&quot;&amp;gt;
                &amp;lt;default&amp;gt;50&amp;lt;/default&amp;gt;
                &amp;lt;variable&amp;gt;SERVO4&amp;lt;/variable&amp;gt;
                &amp;lt;action&amp;gt;bash -c &quot;echo 4=&quot;$SERVO4&quot;% &amp;gt; /dev/servoblaster&quot;&amp;lt;/action&amp;gt;
                &amp;lt;action type=&quot;refresh&quot;&amp;gt;TEXT4&amp;lt;/action&amp;gt;
              &amp;lt;/vscale&amp;gt;
            &amp;lt;/frame&amp;gt;
          &amp;lt;/hbox&amp;gt;
          &amp;lt;hbox&amp;gt;
            &amp;lt;frame サーボ7(%)&amp;gt;
              &amp;lt;vscale height-request=&quot;200&quot; range-min=&quot;10&quot; range-max=&quot;90&quot; range-step=&quot;1&quot; inverted=&quot;true&quot;&amp;gt;
                &amp;lt;default&amp;gt;50&amp;lt;/default&amp;gt;
                &amp;lt;variable&amp;gt;SERVO7&amp;lt;/variable&amp;gt;
                &amp;lt;action&amp;gt;bash -c &quot;echo 7=&quot;$SERVO7&quot;% &amp;gt; /dev/servoblaster&quot;&amp;lt;/action&amp;gt;
                &amp;lt;action type=&quot;refresh&quot;&amp;gt;TEXT7&amp;lt;/action&amp;gt;
              &amp;lt;/vscale&amp;gt;
            &amp;lt;/frame&amp;gt;
            &amp;lt;frame サーボ6(%)&amp;gt;
              &amp;lt;vscale height-request=&quot;200&quot; range-min=&quot;10&quot; range-max=&quot;90&quot; range-step=&quot;1&quot;&amp;gt;
                &amp;lt;default&amp;gt;50&amp;lt;/default&amp;gt;
                &amp;lt;variable&amp;gt;SERVO6&amp;lt;/variable&amp;gt;
                &amp;lt;action&amp;gt;bash -c &quot;echo 6=&quot;$SERVO6&quot;% &amp;gt; /dev/servoblaster&quot;&amp;lt;/action&amp;gt;
                &amp;lt;action type=&quot;refresh&quot;&amp;gt;TEXT6&amp;lt;/action&amp;gt;
              &amp;lt;/vscale&amp;gt;
            &amp;lt;/frame&amp;gt;
          &amp;lt;/hbox&amp;gt;
        &amp;lt;/vbox&amp;gt;

        &amp;lt;vbox&amp;gt;
          &amp;lt;hbox&amp;gt;
            &amp;lt;button&amp;gt;
              &amp;lt;label&amp;gt;ボタン 1&amp;lt;/label&amp;gt;
              &amp;lt;action&amp;gt;echo $LANG&amp;lt;/action&amp;gt;
            &amp;lt;/button&amp;gt;
            &amp;lt;vbox&amp;gt;
              &amp;lt;button width-request=&quot;110&quot;&amp;gt;
                &amp;lt;label&amp;gt;前進&amp;lt;/label&amp;gt;
                &amp;lt;action&amp;gt;bash -c &quot;$test00&quot;&amp;lt;/action&amp;gt;
              &amp;lt;/button&amp;gt;
              &amp;lt;button&amp;gt;
                &amp;lt;label&amp;gt;後退&amp;lt;/label&amp;gt;
              &amp;lt;/button&amp;gt;
            &amp;lt;/vbox&amp;gt;
            &amp;lt;button&amp;gt;
              &amp;lt;label&amp;gt;ボタン 4&amp;lt;/label&amp;gt;
            &amp;lt;/button&amp;gt;
          &amp;lt;/hbox&amp;gt;
          &amp;lt;vbox&amp;gt;
            &amp;lt;frame&amp;gt;
              &amp;lt;text&amp;gt;
                &amp;lt;variable&amp;gt;TEXT0&amp;lt;/variable&amp;gt;
                &amp;lt;input&amp;gt;echo &quot;echo 0=&quot;$SERVO0&quot;% &amp;gt; /dev/servoblaster&quot;&amp;lt;/input&amp;gt;
              &amp;lt;/text&amp;gt;
              &amp;lt;text&amp;gt;
                &amp;lt;variable&amp;gt;TEXT1&amp;lt;/variable&amp;gt;
                &amp;lt;input&amp;gt;echo &quot;echo 1=&quot;$SERVO1&quot;% &amp;gt; /dev/servoblaster&quot;&amp;lt;/input&amp;gt;
              &amp;lt;/text&amp;gt;
              &amp;lt;text&amp;gt;
                &amp;lt;variable&amp;gt;TEXT2&amp;lt;/variable&amp;gt;
                &amp;lt;input&amp;gt;echo &quot;echo 2=&quot;$SERVO2&quot;% &amp;gt; /dev/servoblaster&quot;&amp;lt;/input&amp;gt;
              &amp;lt;/text&amp;gt;
              &amp;lt;text&amp;gt;
                &amp;lt;variable&amp;gt;TEXT3&amp;lt;/variable&amp;gt;
                &amp;lt;input&amp;gt;echo &quot;echo 3=&quot;$SERVO3&quot;% &amp;gt; /dev/servoblaster&quot;&amp;lt;/input&amp;gt;
              &amp;lt;/text&amp;gt;
              &amp;lt;text&amp;gt;
                &amp;lt;variable&amp;gt;TEXT4&amp;lt;/variable&amp;gt;
               &amp;lt;input&amp;gt;echo &quot;echo 4=&quot;$SERVO4&quot;% &amp;gt; /dev/servoblaster&quot;&amp;lt;/input&amp;gt;
              &amp;lt;/text&amp;gt;
              &amp;lt;text&amp;gt;
                &amp;lt;variable&amp;gt;TEXT5&amp;lt;/variable&amp;gt;
                &amp;lt;input&amp;gt;echo &quot;echo 5=&quot;$SERVO5&quot;% &amp;gt; /dev/servoblaster&quot;&amp;lt;/input&amp;gt;
              &amp;lt;/text&amp;gt;
              &amp;lt;text&amp;gt;
                &amp;lt;variable&amp;gt;TEXT6&amp;lt;/variable&amp;gt;
                &amp;lt;input&amp;gt;echo &quot;echo 6=&quot;$SERVO6&quot;% &amp;gt; /dev/servoblaster&quot;&amp;lt;/input&amp;gt;
              &amp;lt;/text&amp;gt;
              &amp;lt;text&amp;gt;
                &amp;lt;variable&amp;gt;TEXT7&amp;lt;/variable&amp;gt;
                &amp;lt;input&amp;gt;echo &quot;echo 7=&quot;$SERVO7&quot;% &amp;gt; /dev/servoblaster&quot;&amp;lt;/input&amp;gt;
              &amp;lt;/text&amp;gt;
            &amp;lt;/frame&amp;gt;
          &amp;lt;/vbox&amp;gt;
          &amp;lt;entry&amp;gt;
            &amp;lt;variable&amp;gt;FILE0&amp;lt;/variable&amp;gt;
            &amp;lt;default&amp;gt;&quot;./temp.txt&quot;&amp;lt;/default&amp;gt;
          &amp;lt;/entry&amp;gt;
          &amp;lt;button&amp;gt;
            &amp;lt;label&amp;gt;新規作成&amp;lt;/label&amp;gt;
            &amp;lt;action&amp;gt;echo &quot;#!/bin/bash&quot; &amp;gt; $FILE0&amp;lt;/action&amp;gt;
            &amp;lt;action&amp;gt;echo &quot;&quot; &amp;gt;&amp;gt; $FILE0&amp;lt;/action&amp;gt;
            &amp;lt;action&amp;gt;echo &quot;echo 0=&quot;$SERVO0&quot;% &amp;gt; /dev/servoblaster&quot; &amp;gt;&amp;gt; $FILE0&amp;lt;/action&amp;gt;
            &amp;lt;action&amp;gt;echo &quot;echo 1=&quot;$SERVO1&quot;% &amp;gt; /dev/servoblaster&quot; &amp;gt;&amp;gt; $FILE0&amp;lt;/action&amp;gt;
            &amp;lt;action&amp;gt;echo &quot;echo 2=&quot;$SERVO2&quot;% &amp;gt; /dev/servoblaster&quot; &amp;gt;&amp;gt; $FILE0&amp;lt;/action&amp;gt;
            &amp;lt;action&amp;gt;echo &quot;echo 3=&quot;$SERVO3&quot;% &amp;gt; /dev/servoblaster&quot; &amp;gt;&amp;gt; $FILE0&amp;lt;/action&amp;gt;
            &amp;lt;action&amp;gt;echo &quot;echo 4=&quot;$SERVO4&quot;% &amp;gt; /dev/servoblaster&quot; &amp;gt;&amp;gt; $FILE0&amp;lt;/action&amp;gt;
            &amp;lt;action&amp;gt;echo &quot;echo 5=&quot;$SERVO5&quot;% &amp;gt; /dev/servoblaster&quot; &amp;gt;&amp;gt; $FILE0&amp;lt;/action&amp;gt;
            &amp;lt;action&amp;gt;echo &quot;echo 6=&quot;$SERVO6&quot;% &amp;gt; /dev/servoblaster&quot; &amp;gt;&amp;gt; $FILE0&amp;lt;/action&amp;gt;
            &amp;lt;action&amp;gt;echo &quot;echo 7=&quot;$SERVO7&quot;% &amp;gt; /dev/servoblaster&quot; &amp;gt;&amp;gt; $FILE0&amp;lt;/action&amp;gt;
          &amp;lt;/button&amp;gt;
          &amp;lt;button&amp;gt;
            &amp;lt;label&amp;gt;ポーズ追加&amp;lt;/label&amp;gt;
            &amp;lt;action&amp;gt;echo &quot;&quot; &amp;gt;&amp;gt; $FILE0&amp;lt;/action&amp;gt;
            &amp;lt;action&amp;gt;echo &quot;sleep 1&quot; &amp;gt;&amp;gt; $FILE0&amp;lt;/action&amp;gt;
            &amp;lt;action&amp;gt;echo &quot;&quot; &amp;gt;&amp;gt; $FILE0&amp;lt;/action&amp;gt;
            &amp;lt;action&amp;gt;echo &quot;echo 0=&quot;$SERVO0&quot;% &amp;gt; /dev/servoblaster&quot; &amp;gt;&amp;gt; $FILE0&amp;lt;/action&amp;gt;
            &amp;lt;action&amp;gt;echo &quot;echo 1=&quot;$SERVO1&quot;% &amp;gt; /dev/servoblaster&quot; &amp;gt;&amp;gt; $FILE0&amp;lt;/action&amp;gt;
            &amp;lt;action&amp;gt;echo &quot;echo 2=&quot;$SERVO2&quot;% &amp;gt; /dev/servoblaster&quot; &amp;gt;&amp;gt; $FILE0&amp;lt;/action&amp;gt;
            &amp;lt;action&amp;gt;echo &quot;echo 3=&quot;$SERVO3&quot;% &amp;gt; /dev/servoblaster&quot; &amp;gt;&amp;gt; $FILE0&amp;lt;/action&amp;gt;
            &amp;lt;action&amp;gt;echo &quot;echo 4=&quot;$SERVO4&quot;% &amp;gt; /dev/servoblaster&quot; &amp;gt;&amp;gt; $FILE0&amp;lt;/action&amp;gt;
            &amp;lt;action&amp;gt;echo &quot;echo 5=&quot;$SERVO5&quot;% &amp;gt; /dev/servoblaster&quot; &amp;gt;&amp;gt; $FILE0&amp;lt;/action&amp;gt;
            &amp;lt;action&amp;gt;echo &quot;echo 6=&quot;$SERVO6&quot;% &amp;gt; /dev/servoblaster&quot; &amp;gt;&amp;gt; $FILE0&amp;lt;/action&amp;gt;
            &amp;lt;action&amp;gt;echo &quot;echo 7=&quot;$SERVO7&quot;% &amp;gt; /dev/servoblaster&quot; &amp;gt;&amp;gt; $FILE0&amp;lt;/action&amp;gt;
          &amp;lt;/button&amp;gt;
        &amp;lt;/vbox&amp;gt;

        &amp;lt;vbox&amp;gt;
          &amp;lt;hbox&amp;gt;
            &amp;lt;frame サーボ0(%)&amp;gt;
              &amp;lt;vscale height-request=&quot;200&quot; range-min=&quot;10&quot; range-max=&quot;90&quot; range-step=&quot;1&quot; inverted=&quot;true&quot;&amp;gt;
                &amp;lt;default&amp;gt;50&amp;lt;/default&amp;gt;
                &amp;lt;variable&amp;gt;SERVO0&amp;lt;/variable&amp;gt;
                &amp;lt;action&amp;gt;bash -c &quot;echo 0=&quot;$SERVO0&quot;% &amp;gt; /dev/servoblaster&quot;&amp;lt;/action&amp;gt;
                &amp;lt;action type=&quot;refresh&quot;&amp;gt;TEXT0&amp;lt;/action&amp;gt;
              &amp;lt;/vscale&amp;gt;
            &amp;lt;/frame&amp;gt;
            &amp;lt;frame サーボ1(%)&amp;gt;
              &amp;lt;vscale height-request=&quot;200&quot; range-min=&quot;10&quot; range-max=&quot;90&quot; range-step=&quot;1&quot; inverted=&quot;true&quot;&amp;gt;
                &amp;lt;default&amp;gt;50&amp;lt;/default&amp;gt;
                &amp;lt;variable&amp;gt;SERVO1&amp;lt;/variable&amp;gt;
                &amp;lt;action&amp;gt;bash -c &quot;echo 1=&quot;$SERVO1&quot;% &amp;gt; /dev/servoblaster&quot;&amp;lt;/action&amp;gt;
                &amp;lt;action type=&quot;refresh&quot;&amp;gt;TEXT1&amp;lt;/action&amp;gt;
              &amp;lt;/vscale&amp;gt;
            &amp;lt;/frame&amp;gt;
          &amp;lt;/hbox&amp;gt;
          &amp;lt;hbox&amp;gt;
            &amp;lt;frame サーボ2(%)&amp;gt;
              &amp;lt;vscale height-request=&quot;200&quot; range-min=&quot;10&quot; range-max=&quot;90&quot; range-step=&quot;1&quot; inverted=&quot;true&quot;&amp;gt;
                &amp;lt;default&amp;gt;50&amp;lt;/default&amp;gt;
                &amp;lt;variable&amp;gt;SERVO2&amp;lt;/variable&amp;gt;
                &amp;lt;action&amp;gt;bash -c &quot;echo 2=&quot;$SERVO2&quot;% &amp;gt; /dev/servoblaster&quot;&amp;lt;/action&amp;gt;
                &amp;lt;action type=&quot;refresh&quot;&amp;gt;TEXT2&amp;lt;/action&amp;gt;
              &amp;lt;/vscale&amp;gt;
            &amp;lt;/frame&amp;gt;
            &amp;lt;frame サーボ3(%)&amp;gt;
              &amp;lt;vscale height-request=&quot;200&quot; range-min=&quot;10&quot; range-max=&quot;90&quot; range-step=&quot;1&quot;&amp;gt;
                &amp;lt;default&amp;gt;50&amp;lt;/default&amp;gt;
                &amp;lt;variable&amp;gt;SERVO3&amp;lt;/variable&amp;gt;
                &amp;lt;action&amp;gt;bash -c &quot;echo 3=&quot;$SERVO3&quot;% &amp;gt; /dev/servoblaster&quot;&amp;lt;/action&amp;gt;
                &amp;lt;action type=&quot;refresh&quot;&amp;gt;TEXT3&amp;lt;/action&amp;gt;
              &amp;lt;/vscale&amp;gt;
            &amp;lt;/frame&amp;gt;
          &amp;lt;/hbox&amp;gt;
        &amp;lt;/vbox&amp;gt;
      &amp;lt;/hbox&amp;gt;
    &amp;lt;/vbox&amp;gt;
  &amp;lt;/window&amp;gt;
&#39;

gtkdialog -p MAIN_DIALOG -c 
&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://aoo10yan.blogspot.com/feeds/8568522444206532960/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://aoo10yan.blogspot.com/2016/06/blog-post.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7359781935835547652/posts/default/8568522444206532960'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7359781935835547652/posts/default/8568522444206532960'/><link rel='alternate' type='text/html' href='http://aoo10yan.blogspot.com/2016/06/blog-post.html' title='修正「簡易ポーズエディタ」'/><author><name>AO_o10yan</name><uri>http://www.blogger.com/profile/00449541977510719198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3fajraWK33bSVQyzvgfPzJwjmd81kQ5d81pXbIXVZvgIQb1yqYhstz-4wRtB9jqYQS7XX50WUJzsFjcvbFuTgiAuKZ1uMQDq9rmgcXIRKEhX7Xo-vixAQG2jBHMhfrMcNLrCHmm9F2hqm/s72-c/2016-06-05--1465105262_644x509_scrot.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7359781935835547652.post-6835880956539568987</id><published>2016-05-15T13:30:00.000+09:00</published><updated>2020-03-07T16:17:45.048+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="arch"/><category scheme="http://www.blogger.com/atom/ns#" term="linux"/><category scheme="http://www.blogger.com/atom/ns#" term="raspberry pi"/><title type='text'>Raspberry Pi　Arch Linux ARMでのWiringPi事情</title><content type='html'>&lt;h4&gt;&amp;nbsp;&lt;i&gt;The wiringpi2 module has been deprecated, please &#39;import wiringpi&#39; instead.&lt;/i&gt;&lt;/h4&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKQ2LtOkfj08Q_ZpXP45TM36sfeOkt-kjoIp_81DPZhQSwds2PwbiWcfWDkJWQ3eg_lNYVHqU0xr1j20MrRTJvaojHBrV_5DR6BtQjsPIxXzTHbFYiPxBuhJK7qjcjp-3sfoQdg0uW9M13/s1600/2016-05-16--1463400701_755x482_scrot.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKQ2LtOkfj08Q_ZpXP45TM36sfeOkt-kjoIp_81DPZhQSwds2PwbiWcfWDkJWQ3eg_lNYVHqU0xr1j20MrRTJvaojHBrV_5DR6BtQjsPIxXzTHbFYiPxBuhJK7qjcjp-3sfoQdg0uW9M13/s1600/2016-05-16--1463400701_755x482_scrot.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
以前&lt;a href=&quot;http://aoo10yan.blogspot.jp/2015/09/raspberry-pi-241.html&quot; target=&quot;&quot;&gt;「4足歩行ロボットを作ってみよう（その1）」&lt;/a&gt;でWiringPiを紹介したが、&lt;br /&gt;
その時と事情が変わった模様。&lt;br /&gt;
&lt;br /&gt;
前回は、Python用のラッパーWiringPi2-Pythonを使ったが、2016/5/15現在&lt;br /&gt;
そのままでは動かない事が分かった。&lt;br /&gt;
&lt;br /&gt;
改めて、WiringPiをインストールして動作確認したので、その方法を書く。&lt;br /&gt;
&lt;br /&gt;
クリーンな状態からやり直すためWiringPiをアンインストールし前回&quot;git clone&quot;した&lt;br /&gt;
ディレクトリを削除しておく。&lt;br /&gt;
&lt;br /&gt;
WiringPiをインストール&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-bash linenums&quot;&gt;$ sudo pacman -S wiringpi&lt;/pre&gt;&lt;br /&gt;
こちら &lt;a href=&quot;https://github.com/WiringPi/WiringPi-Python&quot; target=&quot;_blank&quot;&gt;https://github.com/WiringPi/WiringPi-Python&lt;/a&gt;のREADME.mdを参照しつつ&lt;br /&gt;
ツール関係をインストール&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-bash linenums&quot;&gt;$ sudo pacman -S python-setuptools swig&lt;/pre&gt;&lt;br /&gt;
GITからWiringPi-Pythonをインストール&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-bash linenums&quot;&gt;$ git clone --recursive https://github.com/WiringPi/WiringPi-Python.git
$ cd ./WiringPi-Python
$ swig -python wiringpi.i
$ sudo python3 setup.py install
&lt;/pre&gt;&lt;br /&gt;
&lt;span style=&quot;color: red;&quot;&gt;&lt;b&gt;※上記のswigを忘れない事！！※ &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
これでラッパーが使えるようになるが、Python3でラッパーを呼び出す際に&lt;br /&gt;
&quot;import wiringpi2&quot;としていたのが、&quot;import wiringpi&quot;となるので、以前に書いた&lt;br /&gt;
コードがあれば&lt;span style=&quot;color: red;&quot;&gt;&lt;b&gt;修正&lt;/b&gt;&lt;/span&gt;しておく&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhfzIh7put9CIlHL96H8fWHx7PGKr8IZT1iX7a69iq4KpQZ-UMfljZxLLNOduPxDyDgzNHPGokVAjs3lElHNpby7Djq0QqjHuChKM2BvR8-P2oQ1XIXuHwCzL5blpTMr93k7Y0yodumaX0J/s1600/2016-05-15--1463286338_809x443_scrot.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhfzIh7put9CIlHL96H8fWHx7PGKr8IZT1iX7a69iq4KpQZ-UMfljZxLLNOduPxDyDgzNHPGokVAjs3lElHNpby7Djq0QqjHuChKM2BvR8-P2oQ1XIXuHwCzL5blpTMr93k7Y0yodumaX0J/s1600/2016-05-15--1463286338_809x443_scrot.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;Python3で&quot;import wiringpi2&quot;とすると&quot;ImportError&quot;になる。&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&lt;span style=&quot;color: red;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;&lt;b&gt;※追記1（2016/05/15　16:50）※&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: red;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;&lt;b&gt;上記の方法でなくとも、別途&quot;python-pip&quot;をインストールの上で、&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-bash linenums&quot;&gt;$ sudo pip3 install wiringpi&lt;/pre&gt;&lt;span style=&quot;color: red;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;&lt;b&gt;することで、簡単にインストール出来ました。&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;color: red;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;&lt;b&gt;&amp;nbsp;※追記2（2017/04/10　20:10）※&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
kernelが4.9系の場合は、&lt;b&gt;&lt;a href=&quot;https://github.com/neuralpi/WiringPi-Python&quot; target=&quot;_blank&quot;&gt;こちらのneuralassemblyさんの修正版&lt;/a&gt;&lt;/b&gt;をインストールしてください。&lt;br /&gt;
（pip3でインストールしていた場合は、予めアンインストールしておいてください）</content><link rel='replies' type='application/atom+xml' href='http://aoo10yan.blogspot.com/feeds/6835880956539568987/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://aoo10yan.blogspot.com/2016/05/raspberry-piarch-linuxwiringpi.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7359781935835547652/posts/default/6835880956539568987'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7359781935835547652/posts/default/6835880956539568987'/><link rel='alternate' type='text/html' href='http://aoo10yan.blogspot.com/2016/05/raspberry-piarch-linuxwiringpi.html' title='Raspberry Pi　Arch Linux ARMでのWiringPi事情'/><author><name>AO_o10yan</name><uri>http://www.blogger.com/profile/00449541977510719198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKQ2LtOkfj08Q_ZpXP45TM36sfeOkt-kjoIp_81DPZhQSwds2PwbiWcfWDkJWQ3eg_lNYVHqU0xr1j20MrRTJvaojHBrV_5DR6BtQjsPIxXzTHbFYiPxBuhJK7qjcjp-3sfoQdg0uW9M13/s72-c/2016-05-16--1463400701_755x482_scrot.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7359781935835547652.post-1650275735132242512</id><published>2016-03-13T09:30:00.000+09:00</published><updated>2016-03-14T20:55:25.053+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="linux"/><category scheme="http://www.blogger.com/atom/ns#" term="scratch"/><title type='text'>Scratch　フラクタル樹形を描いてみよう</title><content type='html'>前回、Scratchでコッホ曲線を描いた。今回はフラクタル樹形。&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjV4pKFXKTzS8DRYgymTKmeBVxEbdqBfOXSjn94NdKEl73nW5vthoFs3jlT1bc01tK8R1qZxybaCjHk5cFh1NBsPg9hRoiriwnIv3Btgb_986-PoFapJfuEvR9xbYCGR0hb5w90Oe4KMdzT/s1600/2016-03-12--1457775397_482x401_scrot.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;266&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjV4pKFXKTzS8DRYgymTKmeBVxEbdqBfOXSjn94NdKEl73nW5vthoFs3jlT1bc01tK8R1qZxybaCjHk5cFh1NBsPg9hRoiriwnIv3Btgb_986-PoFapJfuEvR9xbYCGR0hb5w90Oe4KMdzT/s320/2016-03-12--1457775397_482x401_scrot.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;a href=&quot;https://scratch.mit.edu/projects/100926629/&quot;&gt;https://scratch.mit.edu/projects/100926629/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
なにかフラクタル図形を描くことが目的に成ってるみたいだけど、ちょっと違う。&lt;br /&gt;
&lt;br /&gt;
私は再帰処理は、&lt;b&gt;&lt;span style=&quot;color: red;&quot;&gt;理解できない&lt;/span&gt;&lt;/b&gt;ので使いたくない。&lt;br /&gt;
だから、再帰処理を使わなくても再帰処理っぽいことはできないか？と思う。&lt;br /&gt;
&lt;br /&gt;
で、再帰処理を使えば簡単にできるフラクタル図形だけど、これを再帰処理なしで&lt;br /&gt;
やってみよう。と言うのが目的。&lt;br /&gt;
要するに&lt;span style=&quot;color: red;&quot;&gt;&lt;b&gt;『再帰処理が嫌いだ！』&lt;/b&gt;&lt;/span&gt;って言いたい訳。&lt;br /&gt;
&lt;br /&gt;
で、見た目は同じスクリプト内で自分を呼び出している様に見えるけど、&lt;br /&gt;
それは決して『再帰』している訳ではない。&lt;br /&gt;
単純に同じスクリプトを何回も実行しているに過ぎないので、&lt;br /&gt;
&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-size: large;&quot;&gt;「&lt;b&gt;そこんとこ宜しく&lt;/b&gt;！」&lt;/span&gt;&lt;/span&gt;なのだ。 &lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMmeEvJDVVGp58h3BN-PJ4VNuqsatVyYu5FlE90RHnB6POPUeDtdSDkI8wRbTVpqG3KpJEki0mtvoDnF2tJ6DTEsvrWIocu9DqYipgDa_y4GSR2_cw7mMnXmgH3q_8Bnr2CgC10QITOnzy/s1600/2016-03-13--1457828890_484x404_scrot.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;267&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMmeEvJDVVGp58h3BN-PJ4VNuqsatVyYu5FlE90RHnB6POPUeDtdSDkI8wRbTVpqG3KpJEki0mtvoDnF2tJ6DTEsvrWIocu9DqYipgDa_y4GSR2_cw7mMnXmgH3q_8Bnr2CgC10QITOnzy/s320/2016-03-13--1457828890_484x404_scrot.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;a href=&quot;https://scratch.mit.edu/projects/101234609/&quot;&gt;https://scratch.mit.edu/projects/101234609/&lt;/a&gt;&lt;br /&gt;
（これは、作り直すかもしれない。現状では、パラメータの変更は根元の二股へ&lt;br /&gt;
戻った以降に反映されるが、その前でも反映できるようにしたいから）&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;※追記（2016/03/14　20:55）※&lt;br /&gt;
描画中に随時変更可能＆パラメータのランダム生成型を作りました。 &lt;br /&gt;
&lt;a href=&quot;https://scratch.mit.edu/projects/100445168/&quot;&gt;https://scratch.mit.edu/projects/100445168/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYTgZSYj3Yh7KK2jkmGhgHjwW1BQZr3V1RWFIg0TIJoBUvDMc3WgpMJNNw7-5syjRVM9XaF54VDnZBLqE9xVXkldrUErSzX-Ad7KDSuAYR3K92ApasOAFsHj0nqZy48vhT8x2XSrI8wuBF/s1600/2016-03-14--1457956463_487x405_scrot.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;266&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYTgZSYj3Yh7KK2jkmGhgHjwW1BQZr3V1RWFIg0TIJoBUvDMc3WgpMJNNw7-5syjRVM9XaF54VDnZBLqE9xVXkldrUErSzX-Ad7KDSuAYR3K92ApasOAFsHj0nqZy48vhT8x2XSrI8wuBF/s320/2016-03-14--1457956463_487x405_scrot.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://aoo10yan.blogspot.com/feeds/1650275735132242512/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://aoo10yan.blogspot.com/2016/03/scratch.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7359781935835547652/posts/default/1650275735132242512'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7359781935835547652/posts/default/1650275735132242512'/><link rel='alternate' type='text/html' href='http://aoo10yan.blogspot.com/2016/03/scratch.html' title='Scratch　フラクタル樹形を描いてみよう'/><author><name>AO_o10yan</name><uri>http://www.blogger.com/profile/00449541977510719198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjV4pKFXKTzS8DRYgymTKmeBVxEbdqBfOXSjn94NdKEl73nW5vthoFs3jlT1bc01tK8R1qZxybaCjHk5cFh1NBsPg9hRoiriwnIv3Btgb_986-PoFapJfuEvR9xbYCGR0hb5w90Oe4KMdzT/s72-c/2016-03-12--1457775397_482x401_scrot.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7359781935835547652.post-2894159380586854285</id><published>2016-02-28T17:51:00.000+09:00</published><updated>2016-02-28T19:40:53.887+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="linux"/><category scheme="http://www.blogger.com/atom/ns#" term="raspberry pi"/><category scheme="http://www.blogger.com/atom/ns#" term="scratch"/><title type='text'>Scratch　ローカル変数？？</title><content type='html'>&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvW1pLpUJeQ32AlNU69ZRdtBCfBu5WccAc548X5a9TQnWtSNVZAerOHpWqwv3gyy7jyM5_7vIpmA7EO0Tgxig0FbAsjMIwj3MoPt0Fcle5A3hyphenhyphenD_1j_jwcOnokFzWCjEXhXKNrqxVRZTqy/s1600/2016-02-28--1456648711_378x264_scrot.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;223&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvW1pLpUJeQ32AlNU69ZRdtBCfBu5WccAc548X5a9TQnWtSNVZAerOHpWqwv3gyy7jyM5_7vIpmA7EO0Tgxig0FbAsjMIwj3MoPt0Fcle5A3hyphenhyphenD_1j_jwcOnokFzWCjEXhXKNrqxVRZTqy/s320/2016-02-28--1456648711_378x264_scrot.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Scratchで変数を作る時、「すべてのスプライト用」「このスプライトのみ」を&lt;br /&gt;
選択できる。&lt;br /&gt;
&lt;br /&gt;
これをもって、「すべてのスプライト用」をグローバル変数、&lt;br /&gt;
&amp;nbsp;「このスプライトのみ」をローカル変数と解説している記事をよく目にする。&lt;br /&gt;
&lt;b&gt;&lt;span style=&quot;color: red;&quot;&gt;これは首を傾げずにはいられないですよね。&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;或るスプライトに属する変数ではあるけど、それって、そのスプライトに関する&lt;br /&gt;
全てのスクリプトで参照・変更できるんですよね、、、。&lt;br /&gt;
スクリプト（プロシージャ）内でのみ機能する変数ではないので、それを単純に&lt;br /&gt;
ローカル変数として紹介してしまうのは、どうなんでしょう。&lt;br /&gt;
&lt;br /&gt;
（2.0で定義ブロックってのが作れるらしいですが、その定義内にスコープが限定される&lt;br /&gt;
変数があるっぽいですね。） &lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://aoo10yan.blogspot.com/feeds/2894159380586854285/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://aoo10yan.blogspot.com/2016/02/scratch_28.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7359781935835547652/posts/default/2894159380586854285'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7359781935835547652/posts/default/2894159380586854285'/><link rel='alternate' type='text/html' href='http://aoo10yan.blogspot.com/2016/02/scratch_28.html' title='Scratch　ローカル変数？？'/><author><name>AO_o10yan</name><uri>http://www.blogger.com/profile/00449541977510719198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvW1pLpUJeQ32AlNU69ZRdtBCfBu5WccAc548X5a9TQnWtSNVZAerOHpWqwv3gyy7jyM5_7vIpmA7EO0Tgxig0FbAsjMIwj3MoPt0Fcle5A3hyphenhyphenD_1j_jwcOnokFzWCjEXhXKNrqxVRZTqy/s72-c/2016-02-28--1456648711_378x264_scrot.png" height="72" width="72"/><thr:total>0</thr:total></entry></feed>