« 2021年6月 | トップページ | 2021年8月 »

2021年7月26日 (月)

Yolov4で物体検出した対象にIDつけて追いかけ(トラッキング)つつ、ある場所を通過した人をカウントするやつ作ってみた

まるでどこかのラノベのような長いタイトルで申し訳ないですが、表題の通りのもの、作りました。

Track02  

用途としては、ある場所を通過した人の人数を数える、という、イベントなどでは使いたくなるやつです。

(ただし、今回のは出入り方向のどちらも区別なくカウントします)

もちろん、一から作ったわけではなく、ベースの仕組みがあったので、それを改造して作成。

ベースとしたコードは、こちら。

GitHub - LeonLok/Deep-SORT-YOLOv4: People detection and optional tracking with Tensorflow backend.

「Deep Sort Yolov4」という、Yolov4を使って物体検出(デフォルトでは人)をさせて、それぞれにIDをつけて追跡する、いわゆる「物体追跡」のコードです。

物体検出には、検出精度が高くて定評な(かつ商用利用も安心な)Yolov4を使ってます。

しかもこのコード、TensorFlow 1.14とKeras 2.2.4という、我が家の環境でも動きます。

(なお、TensorFlow 2.0版も同梱されてます)

ここでは、Windows 10+Python 3.7.9+TensorFlow 1.14+Keras 2.2.4で話を進めます。

まず、上のコードをZIPでダウンロードし、展開。

Deep-SORT-YOLOv4-master」というフォルダができるので、その中の「tensorflow1.14」‐「deep-sort-yolov4」に入ります。

で、まずはREADME.mdのQuick startに従い、既存の学習モデルを入手、変換します。

ここから「yolov4.weights」が入手できるので、それを上のフォルダに入れて、

> python convert.py

と入力し、実行。

yolo4.h5」というファイルができるので、それを「model_data」というフォルダに移動。

ここでまず、

> python demo.py

を動かしてみます。

Track03

多分、デフォルトではこんな感じの絵が出てくるはずです。

歩行者にそれぞれ個別のIDが割り振られて、ちゃんと追跡されているのが分かるかと思います。

読み込む動画を変えたいときは、「demo.py」の中の41行目にある

file_path = 'video.webm'

のイコールの後ろ、「video.webm」のところを処理させたい動画ファイル名に変えてやればOKです。

Track01

こんな感じになります。

今回の目的は、ある場所の通過地点の人の数をカウントすることが目的なため、上側から撮影した俯瞰動画の方が都合がいいです。

ということで、ここでは以前に書いた「Jetson Nanoの固定カメラで人の動きを分析する「動線分析」をやらせてみた: EeePCの軌跡」で、Jetson Nanoの中に入っていた「pedestrians.mp4」を使うことにします。

さて、このままでは、全然人をカウントしてくれません。そこで、このdemo.pyを以下のように書き換えます。

demo.py


#! /usr/bin/env python
# -*- coding: utf-8 -*-

from __future__ import division, print_function, absolute_import

from timeit import time
import warnings
import cv2
import numpy as np
from PIL import Image
from yolo import YOLO

from deep_sort import preprocessing
from deep_sort import nn_matching
from deep_sort.detection import Detection
from deep_sort.detection_yolo import Detection_YOLO
from deep_sort.tracker import Tracker
from tools import generate_detections as gdet
import imutils.video
from videocaptureasync import VideoCaptureAsync

warnings.filterwarnings('ignore')

def main(yolo):
  with open('test.csv','w'as f:
    # Definition of the parameters
    max_cosine_distance = 0.3
    nn_budget = None
    nms_max_overlap = 1.0
    
    # Deep SORT
    model_filename = 'model_data/mars-small128.pb'
    encoder = gdet.create_box_encoder(model_filename, batch_size=1)
    
    metric = nn_matching.NearestNeighborDistanceMetric("cosine", max_cosine_distance, nn_budget)
    tracker = Tracker(metric)

    tracking = True
    writeVideo_flag = True
    asyncVideo_flag = False

    file_path = 'pedestrians.mp4'
    if asyncVideo_flag :
        video_capture = VideoCaptureAsync(file_path)
    else:
        video_capture = cv2.VideoCapture(file_path)

    if asyncVideo_flag:
        video_capture.start()

    if writeVideo_flag:
        if asyncVideo_flag:
            w = int(video_capture.cap.get(3))
            h = int(video_capture.cap.get(4))
        else:
            w = int(video_capture.get(3))
            h = int(video_capture.get(4))
        fourcc = cv2.VideoWriter_fourcc(*'XVID')
        out = cv2.VideoWriter('output_yolov4.avi', fourcc, 30, (w, h))
        frame_index = -1

    fps = 0.0
    fps_imutils = imutils.video.FPS().start()

    count = 0

    while True:
        count+=1
        ret, frame = video_capture.read()  # frame shape 640*480*3
        if ret != True:
             break

        t1 = time.time()

        if count==1:
            cv2.imwrite('test.jpg',frame)

        image = Image.fromarray(frame[...,::-1])  # bgr to rgb
        boxes, confidence, classes = yolo.detect_image(image)

        if tracking:
            features = encoder(frame, boxes)

            detections = [Detection(bbox, confidence, cls, feature) for bbox, confidence, cls, feature in
                          zip(boxes, confidence, classes, features)]
        else:
            detections = [Detection_YOLO(bbox, confidence, clsfor bbox, confidence, cls in
                          zip(boxes, confidence, classes)]

        # Run non-maxima suppression.
        boxes = np.array([d.tlwh for d in detections])
        scores = np.array([d.confidence for d in detections])
        indices = preprocessing.non_max_suppression(boxes, nms_max_overlap, scores)
        detections = [detections[i] for i in indices]

        for det in detections:
            bbox = det.to_tlbr()
            score = "%.2f" % round(det.confidence * 1002) + "%"
            cv2.rectangle(frame, (int(bbox[0]), int(bbox[1])), (int(bbox[2]), int(bbox[3])), (25500), 2)
            if len(classes) > 0:
                cls = det.cls
                cv2.putText(frame, str(cls) + " " + score, (int(bbox[0]), int(bbox[3])), 0,
                            1e-3 * frame.shape[0], (02550), 1)

        if tracking:
            # Call the tracker
            tracker.predict()
            tracker.update(detections)

            for track in tracker.tracks:
                if not track.is_confirmed() or track.time_since_update > 1:
                    continue
                bbox = track.to_tlbr()
                cv2.rectangle(frame, (int(bbox[0]), int(bbox[1])), (int(bbox[2]), int(bbox[3])), (255255255), 2)
                cv2.putText(frame, "ID: " + str(track.track_id), (int(bbox[0]), int(bbox[1])), 0,
                            1e-3 * frame.shape[0], (02550), 1)
                track_info = str(count) + ' , ' + str(track.track_id) + ' , ' + str((int(bbox[0]) + int(bbox[2]))/2) + ' , ' + str((int(bbox[1]) + int(bbox[3]))/2)
                print(track_info,file=f)
                print(track_info)

        cv2.imshow('', frame)

        if writeVideo_flag: # and not asyncVideo_flag:
            # save a frame
            out.write(frame)
            frame_index = frame_index + 1

        fps_imutils.update()

        if not asyncVideo_flag:
            fps = (fps + (1./(time.time()-t1))) / 2
            print("FPS = %f"%(fps))
        
        # Press Q to stop!
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

    fps_imutils.stop()
    print('imutils FPS: {}'.format(fps_imutils.fps()))

    if asyncVideo_flag:
        video_capture.stop()
    else:
        video_capture.release()

    if writeVideo_flag:
        out.release()

    cv2.destroyAllWindows()

if __name__ == '__main__':
    main(YOLO())

ところどころ書き換えてますが、要するにこれ、最初の1枚目の画像を出力し、画像のコマ数、トラッキングIDとボックスの中心座標を、CSVファイルに吐き出すようにしただけです。

Track04

こんなのが出てきます。左から順に「コマ数」「トラッキングID」「検出ボックス中心のX座標(ピクセル)」「〃 Y座標」。

それを可視化するコードは、こちら。

plot_count.py


import numpy as np
import matplotlib.pyplot as plt
import csv
import math
import cv2

cross_id = []

# 通過判定のボックス範囲
bminx = 673
bmaxx = 711
bminy = 196
bmaxy = 324

# カラーマップを作成
np.random.seed(133)

col_b = np.random.randint(0,255,256)
col_g = np.random.randint(0,255,256)
col_r = np.random.randint(0,255,256)

# 1枚目の画像を読み取り
img = cv2.imread('test.jpg')

with open("./test.csv","r"as f:
  with open('cross_id.csv''w'newline=''as file:
    reader = csv.reader(f)
    for line in reader:
        id = math.floor(float(line[1]))
        x = math.floor(float(line[2]))
        y = math.floor(float(line[3]))

        # id書き込み
        if x>bminx and x<bmaxx and y>bminy and y<bmaxy:
            print(id,file=file)
            cross_id.append(id)

        # 点をプロット
        cv2.circle(img, (x, y), 2color=(int(col_b[id%255]), int(col_g[id%255]) ,int(col_r[id%255]) ), thickness=2)

# 四角形
cv2.rectangle(img, (bminx ,bminy), (bmaxx, bmaxy), (00255),thickness=2)
# 画像書き込み
cv2.imwrite('image.png',img)

# IDの重複を削除
count_id = list(set(cross_id))

# 通過数のカウント表示
print(len(count_id))

# 重複を除いたIDを書き込み
file = open('count_id.csv''w'newline=''
writer = csv.writer(file)
for ele in count_id:
    writer.writerow([ele])

# 結果を表示する。
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
plt.axis('off')
plt.show()

これで得られた画像は、以下。

Track02

各々の人の軌跡の画像が、こんな感じに得られます。

で、真ん中ちょっと右に赤い四角がありますが、このコードは同時に、ここを通過する人の人数をカウントしてます。

赤枠の座標は、上のプログラム中の「bminx」「bmaxx」「bminy」「bmaxy」でそれぞれX、Y座標を指定してます。

で、上のプログラム中に「cross_id」という変数(リスト)がありますが、そこにこの赤枠内を通過したdeep sortが取得したIDが記録されます。

が、実はこの赤枠内を通過している間がすべて記録されるため、同じIDがいくつも記録されてます。

Track05

こんな感じ。

で、この重複部分を削除したのが「count_id」というリストで、

Track06

こうなります。

上の図でも見てわかると思いますが、この赤枠内を通過した人は3人。

で、IDも3つ。

ちゃんと、カウントされていることが分かるかと思います。

なお、実行ターミナル上にもこの「3」という数字が出てきます。

固定カメラで得られた動画と、どこを通過した人数をカウントしたいか、さえ決めれば、カウントしてくれます。

ただし、入場、出場の人数分けをしたいときは、今のところできませんね。またそれは、いずれ考えようかと。

ところで、私がやりたかったのは、実は「人」ではなく「車」のカウント。

ある場所を通過する車の台数をカウントする必要があり、それをさせるためにこれを作りました。

が、このままでこいつ、「人」しかカウントしません。

これを「車」用に変えるには、同じフォルダ内にある「yolo4.py」を開き、その104行目の


if predicted_class != 'person':


if predicted_class != 'car':

に変えてやれば、車をカウントできるようになります。

なお、ラベル名は「model_data」フォルダの中にある「coco_classes.txt」を参照してください。

このラベル内にないものを検出させたい場合は……頑張って、独自データで学習させるしかありませんね。

まあ、たいていは人か車をカウントすることが多いので、その用途でなら上の方法で行けます。

ところで、今回は上の「demo.py」と「plot_cound.py」を別々にしてます。

一緒にしようと思えばできたのですが、トラッキングしたデータをカウントする場所をトライアンドエラーすることを想定し、敢えてコードを分けておきました。

これが一緒だと、試行錯誤するたびに毎回動画処理をすることとなり、ものすごく時間がかかります。

さらに、数か所をはかることになりそうなので、その場合は「plot_cound.py」をコピーして、それぞれの場所のカウントを個別に取る、なんてことも対応できます。

ついでに言うと、入退場を別々に処理させたい場合も、いったんは別々に作ってからやった方がプログラムの試行錯誤もやりやすいかと思ったわけです。

例によって、このブログに載ったコードは、自由に使っていただいてOKです。元々、ベースのコードもそうですし。

ただし利用は、自己責任でお願いいたします。


TensorFlowはじめました3 Object Detection ─ 物体検出 (NextPublishing)

2021年7月23日 (金)

月の土地、買いました

物欲のなされるがままに、これまでもいろいろと変なものを買ってきました。例えば、100兆ドル札(ただしジンバブエドル)等。

が、今度の買い物はスケールだけは大きいです。

Img_0581

なにやら意味深な封筒。その中身は……

Img_0583

3枚の紙が入ってます。

これ、月の土地の所有を証明するものなんです。

左から順に、月の土地の権利書、マップ、そして月憲法。

これを売ってるのはこちら。

 月の土地|ルナエンバシージャパン

要するに、とある人が「月って、個人なら所有できるんじゃねぇ!?」と思い立ち、裁判所やら国連やらに(一応は)お伺いを立てたのちに、それを売却する権利を得た、ということのようです。その行動力に、あっぱれ。

なんだ、そんなもん、本当に月に行ける時代になったら、何の役にも……いやいやいやいや、夢のないことを言っちゃあいけません。とにかく、月の土地が買えるんです。

仮にも「小説家になろう」で宇宙SFを書いている者としては、月の土地の一つや二つは持っておかないとだめじゃないかと思った次第です。

Img_0588

ちなみに、その土地の広さは1エーカー。およそ1200坪。我が家の土地の約25倍の広さです。でかい。

それが、たった(?)の2700円(送料込みで3030円)で買えるんですから、安いものです。

購入した日付は、2021年7月19日。アポロ11号の月着陸52年目の前日……でもありますけど、私の50歳の誕生日です。

Img_0585

ちなみに、場所は大体この辺だそうです。

お近くにお立ち寄りの際は、是非いらしてください。

と、みんなに言ってます。まあ、来れるものなら・・・

意外に赤道に近いので、月の中でも比較的行きやすいところですね。

Img_0586

ちなみに、土地の権利書なのに取説がついています。

Img_0587

早い話が、あの3枚の紙の和訳ですね。なかなかどうして、親切です。

しかし、人類が月に当たり前のようにいける時代は、果たして来るんでしょうか?

そんな時代が、生きている間に訪れたなら、行ってみたいですね。自分の買った土地とやらに。

なお、妻からはすげえバカにされました。。。


月ライト 月ランプ 間接照明 母の日 ギフトシャンデリア インテリア テーブルランプ月のランプ ナイトライト 授乳用ライト タイマー 15cm 3Dプリント usb充電 リモコン タッチ調光 16色切り替え 無段階調光 吊る下げり可能 プレゼント 誕生日 結婚 父の日 引っ越し 進学のお祝い (15cm月ライト)

2021年7月19日 (月)

雑貨屋のノートPC用スタンドでSurface Goを”クラムシェル”風にしてみた

文書を書くことが多いため、稼働率が高めなSurface Goですが、こいつはクラムシェル端末ではないため、座椅子に座って使うときにはちょっと不便な端末。

何とかこいつを”クラムシェル”化してくれるようなケースがないかと探してはみたんですが、ないんですかね、そういう需要って。

と思っていたら、こんなノートPC用スタンドに遭遇。

Img_0571

近所のららぽーと東郷の中にある”AWESOME STORE”という雑貨屋で買いました。お値段、税別980円。

Img_0572

中身はこんな感じ。要するに、この夏の暑い時期のノートPCの裏側に隙を作り、少しでも冷やしてやろうというスタンドです。

Img_0573

こうやって使うのが、正当な使い方(15.6インチのGALLERIA GR1650TGF-Tを載せてます)。

が、店頭の見本を眺めていて、ふと思いつきます。

Img_0574

これを裏返して

Img_0575

こういうものを載せたらどうだろうか?

いやあ、やってみたらまるで測ったかのようにピッタリなサイズ。

Img_0578

特にテープ類で固定せずとも、まあまあの保持力。

こんな感じに持ち上げても、ずれる気配なしです。

Img_0576

後ろはこの”脚”を背もたれにします。

Surface GoのWindowsロゴの辺りに穴があって、まるでこいつ専用のスタンドのようです。

Img_0577

本来は接地用のゴムが、この通り、キーボードをうまいこと保持してくれます。

にしてもこれ、ほんとにSurface Goの幅にピッタリ。狙ってませんかね?

Img_0579

試しに、座椅子の上でクラムシェルっぽく使ってみました。

いい感じですが、やはり動かすと、本体が前に倒れようとすることも。

Img_0580

が、それはそれで、この背もたれに何らか固定してしまえばいいだけの模様。

ここに耐震パッド辺りをつけて貼り付ければ、それで十分保持してくれそうです。

非推奨な使い方ですが、思わぬスタンドの活用法を見つけちゃいました。

当然、同じ大きさのSurface Go 2もいけます。

(たまたま会社で使っているSurface Go 2が手元にあったので、使ってみました)

クラムシェル型が便利で、Surface Laptopが欲しくなる今日この頃でしたが、これなら当分、要らないかなぁ。

しばらく、使ってみます。

マイクロソフト Surface Go 2 [サーフェス ゴー 2] Office Home and Business 2019 / 10.5 インチ PixelSense ディスプレイ /インテル Pentium Gold 4425Y/4GB/64GB プラチナ STV-00012

2021年7月18日 (日)

大須で買い物してきました

大須に行ってきました。

が、実は用事のついでにちょろっと寄っただけなので、寄るところも限定されており、写真も撮ってません。

Img_0562

ということで、戦利品のみを紹介。

USBメモリーと、3極マイク、スピーカー端子の4極化コネクターです。

Img_0563

マイク、スピーカー端子の方は、こういう使い方をするために買いました。

会社のPCと、自宅のGALLERIAが、マイクとスピーカーの端子が分かれており、iPhoneに付属する4極の端子を持つマイク付きイヤホンがそのままでは挿さりません。

この端子、リモート会議時代には必須です。

Img_0564

で、もう一つのUSBメモリーですが、単純に、USBメモリーが欲しかったから購入。で、容量は16GB。

128GBのUSBメモリーは持ってるんですが、あれはRaspberry Piでは使えません。

Raspberry PiとPCとのデータのやり取りには、USBメモリーの方が速くて便利な場合が多くて、32GB以下のメモリーが欲しいなぁと思うこともしばしば。

Img_0565

そういう用途には、これを使ってたんですね。Buffaloの超小型microSDカードアダプター。

こいつに32GBのmicroSDカードを挿して、USBメモリーとして使ってたんですが……

Img_0566

抜き差しの時に、この黄色いのを押しちゃうんですよ。

これを押しちゃうと、中のSDカードが抜けちゃうので、認識しなくなることがしばしば。

あまりに不便すぎて、microSDカードリーダー以外にはあまり使いたくありません。

まあ、普通のサイズのメモリーにすればいいじゃないかとも思われそうですが、小さい方が何かと捗ることもあって、敢えて超小型のメモリーにこだわりました。

で、これで終わりといえば終わりですが。

実はもう一つ、ゲットしたものが。

Img_0567

「大須マップ」です。

表紙の漫画にもある通り、大須商店街の初心者が巡るためのマップです。

Img_0568

小さすぎて申し訳ありませんが、大須商店街の地図と各々の店がびっしりと書かれてます。

Img_0570

大須名物(?)の金玉……「金の玉」も描かれてます。

Img_0569

ページをめくれば、グルメ情報や雑貨屋等、数々の情報が満載です。

なかなかよくできたマップです。

商店街の入り口と、第一アメ横ビルの2階のトイレの前にありました。

大須をめぐりたくなったら、是非このマップ片手にいかがでしょう?

うみゃーがね!名古屋の大須のみそのさん (アクションコミックス)

2021年7月11日 (日)

ケーブルクリップやらRaspberry Pi 4用ケース等を買ってみた

いろいろ買いました。

Img_0520

百均で買ったものと、Amazonから届いたものが入り混じってますが、順に紹介を。

Img_0521

これは、百均で買った結束バンド。

これ、たまに使うんですが、とうとう使い切ったので購入。それだけです。

Img_0522

で、これはケーブルクリップ。買う予定はなかったのですが、店頭で見て思わず購入。

Img_0528

と、いうのも、せっかくディスプレイアームを購入してスッキリしたはずの机の上が、このぴょんぴょんした充電ケーブル類で台無し感があったので、何とかしてやりたいとずっと思っていたところです。

Img_0531

が、こんな感じに、ディスプレイの下面に張り付けちゃえばすっきりするじゃん、と思った次第。

実際、」結構スッキリしました。

Img_0530

使うときは、こんな勢いで引っ張ればヨシ!

Img_0523

で、お次はこれ。

スマホの画面を拡大するっていう、虫眼鏡なやつです。

Img_0527

まあ、要するにこうやって……

Img_0526

スマホの画面が拡大……

とは、なかなかいきませんね。

このレンズ、中央以外はぼやけて、まるで見えません。

Img_0524

もっとも、これを買った目的は、こういう使い方をするためなんですが。

今度、会社でRaspberry Pi電子工作+Pythonな講座をやるので、それをリモート(Zoom)で流そうと思ったら、拡大しないとダメそうだなと思って買ってきたやつです。

中央に持ってくることさえ忘れなければ、どうにか使えそうです。

Img_0532

とまあ、百均の品が前座を務めてくれましたが、いよいよここで本命登場。

端にあった小さな段ボール風の箱の中身は、Raspberry Pi 4用のケースです。これだけ、Amazonでの購入品です。

Img_0533

といっても、上下をアクリル板で囲むだけの簡単なやつ。

見た目は簡素ですが、作るのはこの通り、大変そうです。

このケースにしたのは、側面に隙があった方が、何かと便利そうだったから、というだけの理由です。

早速、組み立て開始。

Img_0534

ところがこのケースの説明文、めちゃくちゃ不親切です。

1コマ目からいきなりアクリル板の表面のフィルムをはがしてから、4本のねじを立ててくれ、プリーズ!

って、書いてあるんですが……

Img_0535

その台座のねじを置こうにも、どう見てもそのままではつきません。

その下から、ねじを通さなきゃいけない模様。

ですが、このアクリル板と台座ネジの間には、どの大きさのねじを使うのかが全く書かれていないので、

Img_0536

この中から、探すしかありません。なんという、不親切な……

Img_0537

で、分かったのは、この組み合わせで使えばいいということ。

Raspberry Piの台座部分のねじは上の細いやつ、ケース上下面をつなぐ長い台座のネジには、太いねじを使う模様。

これに気づけって、素人には無理です、絶対。

Img_0538

で、あっさりした説明書とは裏腹に、実際にはまず普通のネジを穴に通して、

Img_0539

台座となるこのねじを締め付けます。

Img_0540

これを4本分、繰り返します。これでようやく、台座部分が完成。

Img_0541

で、Raspberry Pi 4を載せて、ナットで締めると、

Img_0542

その外側に、長い台座ネジを取り付け。

Img_0543

一方、上面の方には、ファンを取り付けます。

Img_0545

で、あとはこれを外側の4本のねじに止めれば

Img_0546

と、その前に、カメラのフレキシブルケーブルを取り付けます。

Img_0547

で、上面を取り付けます。

これで、ケースは完成。

Img_0548

なお、CPUのヒートシンクとファンの間は、こんな関係です。

なんだかちょっと、ファンの位置がずれてますね。

Img_0544

ちなみに、ヒートシンクが2種類ついてました。

Raspberry Pi 4用と、3B+用がついてました。

が、すでにヒートシンクがついていたため、これは使わずにとっておきます。

Img_0549

で、このケースにカメラを両面テープで固定したのち、以前、3COINSという300円均一の店で買ったスマホスタンドに取り付けます。

こんなことして、何をするのかといえば……

実はこれを使って、Raspberry Pi 4でmediapipeを動かして、人の姿勢を「数値化」してみようと思ってまして。

Img_0551

で、MediaPipeのコードを少し書き換えて、関節の一部の数値をCSVファイルとして出力するやつを作りました。

Img_0552

ちょっと見難いですが、椅子に座っている私を読み込んでおります。

数値もちゃんと、出力してました。

こいつを使って、ちょっと会社で遊んで(?)みようかと企んでます。

ということで、久々の百均 & Raspberry Piケースネタは以上です。

また何かあれば(姿勢推定の話も含め)、このブログで報告します。

Raspberry Pi 4 4B-64GB(技適マーク入)MicroSDHCカード64G/Raspbianシステムプリインストール/カードリーダ /5.1V/3A Type-C スイッチ付電源/MicroHDMI-to-HDMIケーブルライン/三つヒートシンク/簡単に取り付けケース/日本語取扱説明書/24ヶ月保証

2021年7月10日 (土)

無料でKindle読み上げ機を作ってしまったという記事

なかなか、野心的な取り組みですね。

音声読み上げ非対応なKindle本を、読み上げさせようという話です。

無料でKindleを読み上げるソリューション作ってたら、Audibleならぬオレディブルが出来てしまったが一向にかまわんッ - Qiita

KindleにはAudibleというサービスがありますが、オーディオブックに限定されるため、音声対応していない本は読み上げができません。

が、そんな本でも、読み上げ可能にしてしまおうという試みがこの記事。

要するに、Kindle → PDF → png → OCRでテキスト化 → WAV音声という順で、Kindleを音声化するというもの。

正直、大丈夫かな?と思う手順で、しかも自動というわけではないようですが、試みそのものが面白い。

やはりというか、ところどころ読み方がおかしいようですね(特に人名)。とはいえ、意外と使えるようです。

もっとも、耳で聞くだけで理解できるかどうかという問題があるようですが。

そういえば、自作小説を読み上げさせたことがあります。一応、OneNoteには、読み上げ機能があるので。

が、やはり文体の文書を読ませると、なんだかちょっと、違和感があります。

読み上げ機能も、良し悪しですね。

ところでこの元記事のタイトルが、とある漫画のタイトルのようなのですが……ちなみに、どう考えても漫画の読み上げは無理そうです。

バキ外伝 烈海王は異世界転生しても一向にかまわんッッ 1

2021年7月 2日 (金)

Raspberry Pi 4でWindows 11が動く!?

非公式、非推奨、非サポートな方法であることを承知の上で、こちらをご覧ください。

Raspberry Pi 4にARM版 Windows 11をインストールしてみる。 | Miya-Gadget

なんと、Raspberry Pi 4の4GBモデルで、Windows 11のARM版を動かしてしまったというお話。 

動画もありました。

本当に動いてますね。思ったより、スムーズです。やはり、UIがスマホに近づいたからでしょうか?

ただし、こういう無理やりハードな使い方は、たいていは実用性がないというのが落ちです。さすがにアプリケーションを使うのには不便なのではないかと。

話題としては、面白いですけどね。

しかし、Raspberry Pi 4でも動くくらいのOSなら、Surface Go 1でも動かせるようにならなかったのか……

昔は、手のひらサイズの端末でWindowsが動かせることがとてもワクワクしましたけど、今はスマホがあるためか、わざわざ小型の端末でWindowsを動かそうという気持ちにはなれないですよね。

携帯機は、AndroidやiOSで十分。キータイプが多い用途には、12~15インチサイズのノート型PCで。そういう時代です。


Microsoft Windows 10 Home April 2018 Update適用 32bit/64bit 日本語版【最新】|オンラインコード版

« 2021年6月 | トップページ | 2021年8月 »

無料ブログはココログ

スポンサード リンク

ブログ村