シェルスクリプトマガジン

test

Raspberry Pi Pico W/WHで始める電子工作(Vol.88掲載)

投稿日:2024.01.25 | カテゴリー: コード

著者:米田 聡

本連載では、人気のマイコンボード「Raspberry Pi Pico W/WH」を活用していきます。同ボードは、無
線LANやBluetoothの通信機能を搭載し、入手しやすく価格も手頃なので、IoT機器を自作するのに最適なハードウエアです。第4回は、モノクロ有機ELディスプレイと湿温度センサー「DHT-11」で日本語表示の湿温度計を作ります。

シェルスクリプトマガジン Vol.88は以下のリンク先でご購入できます。

図9 温度と湿度を日本語で表示するプログラム(temp_hum.py)

from machine import Pin
from machine import I2C
from ssd1306 import SSD1306_I2C
from display import PinotDisplay
from pnfont import Font
import dht
import time

# ELパネル
i2c=I2C(0, freq=400000)
ssd = SSD1306_I2C(128, 32, i2c)
# pinotライブラリ
fnt = Font('/fonts/shnmk12u.pfn')
disp = PinotDisplay(panel = ssd, font = fnt)
# DHT-11センサー
sensor = dht.DHT11(Pin(15))

while True:
    os_error = False
    try:
        sensor.measure()
    except OSError as e:
        os_error = True
    
    line1 = "温度: {0:2d} C".format(sensor.temperature())
    line2 = "湿度: {0:2d} %".format(sensor.humidity())
    line3 = "DHT-11エラー" if os_error else "                "
    
    # 温度表示
    disp.locate(1, 0)
    disp.text(line1)
    # 湿度表示
    disp.locate(1,12)
    disp.text(line2)
    # エラー表示
    disp.locate(1,24)
    disp.text(line3)
    
    time.sleep(2)

Pythonあれこれ(Vol.88掲載)

投稿日:2024.01.25 | カテゴリー: コード

著者:飯尾 淳

本連載では「Pythonを昔から使っているものの、それほど使いこなしてはいない」という筆者が、いろいろな日常業務をPythonで処理することで、立派な「蛇使い」に育つことを目指します。その過程を温かく見守ってください。皆さんと共に勉強していきましょう。第18回では、米Google社が提供する機械学習フレームワーク「MediaPipe」の顔検出機能を用いて、お遊びのプログラム作成に挑戦します。

シェルスクリプトマガジン Vol.88は以下のリンク先でご購入できます。

図1 顔ランドマーク検出をするコード

import cv2
import mediapipe as mp

spec = mp.solutions.drawing_utils.DrawingSpec(thickness=1,
                                              circle_radius=1)
cap = cv2.VideoCapture(0)
with mp.solutions.face_mesh.FaceMesh(
    min_detection_confidence=0.5, 
    min_tracking_confidence=0.5) as face_mesh:
  while True:
    success, image = cap.read()
    if not success: print("Warning: No camera image"); continue
    image = cv2.cvtColor(cv2.flip(image, 1), cv2.COLOR_BGR2RGB)
    image.flags.writeable = False
    results = face_mesh.process(image)
    # Annotate the face mesh
    image.flags.writeable = True
    image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
    if results.multi_face_landmarks:
      for landmarks in results.multi_face_landmarks:
        mp.solutions.drawing_utils.draw_landmarks(
            image=image, landmark_list=landmarks,
            connections=mp.solutions.face_mesh.FACEMESH_TESSELATION,
            landmark_drawing_spec=spec,
            connection_drawing_spec=spec)
    cv2.imshow('MediaPipe FaceMesh', image)
    if cv2.waitKey(5) & 0xFF == 27: break
cap.release()

図4 「顔ハメ」アプリのコード

import cv2
import numpy as np
from PIL import Image, ImageDraw
import mediapipe as mp

def scaleToHeight(img, height):
  h, w = img.shape[:2]
  width = round(w * (height / h))
  dst = cv2.resize(img, dsize=(width, height))
  return dst
def convertToRGBA(src, type):
  return Image.fromarray(cv2.cvtColor(src, type))\
              .convert('RGBA')
def trimOutside(base, over, loc):
  drw = ImageDraw.Draw(base)
  drw.rectangle([(0, 0), (loc[0]-1, over.size[1]-1)],
                fill=(0, 0, 0))
  drw.rectangle([(loc[0]+over.size[0], 0), 
                 (base.size[0]-1,over.size[1]-1)],
                fill=(0, 0, 0))
def overlayImage(src, overlay, location):
  # convert images to PIL format
  pil_src     = convertToRGBA(src,     cv2.COLOR_BGR2RGB)
  pil_overlay = convertToRGBA(overlay, cv2.COLOR_BGRA2RGBA)
  # conpose two images
  pil_tmp = Image.new('RGBA', pil_src.size, (0, 0, 0, 0))
  pil_tmp.paste(pil_overlay, location, pil_overlay)
  trimOutside(pil_tmp, pil_overlay, location)
  result_image = Image.alpha_composite(pil_src, pil_tmp)
  # convert result to OpenCV format
  return cv2.cvtColor(np.asarray(result_image),
                      cv2.COLOR_RGBA2BGRA)
def decrementTimer(timer, image, p_idx):
  h, w = image.shape[:2]
  if timer < 0:
    p_idx = (p_idx + 1) % len(panels)
    return TIMER_INITIAL_VALUE, p_idx
  elif timer == 30:
    global still
    still = image
    cv2.rectangle(image, (0, 0), (w, h), (255,255,255),
                  thickness=-1)
    return timer - 1, p_idx
  elif timer < 30:
    image = still
    return timer - 1, p_idx
  d, r = timer // 30, timer % 30
  c = 255 / 60 * r + 128
  cv2.putText(image, org=(int(w/2-100), int(h/2+100)), 
              text=str(d),
              fontFace=cv2.FONT_HERSHEY_DUPLEX,
              fontScale=10.0, color=(c, c, c),
              thickness=30,
              lineType=cv2.LINE_AA)
  return timer - 1, p_idx
# prepare the kao_hame_panels
panels = []
panels.append(cv2.imread('img1.png', cv2.IMREAD_UNCHANGED))
panels.append(cv2.imread('img2.png', cv2.IMREAD_UNCHANGED))
panels.append(cv2.imread('img3.png', cv2.IMREAD_UNCHANGED))
# capture from a camera
cap = cv2.VideoCapture(0)
ret, frame = cap.read()
# rescale the kao_hame image
height, width = frame.shape[:2]
for i in range(len(panels)):
  panels[i] = scaleToHeight(panels[i], height)
p_idx = 0
panel = panels[p_idx]
p_height, p_width = panel.shape[:2]
# timing counter
TIMER_INITIAL_VALUE = 119
timer = TIMER_INITIAL_VALUE
with mp.solutions.face_mesh\
                 .FaceMesh(max_num_faces=1,
                           refine_landmarks=True,
                           min_detection_confidence=0.5,
                           min_tracking_confidence=0.5)\
                 as face_mesh:
  while cap.isOpened():
    success, image = cap.read()
    if not success:
      print("Ignoring empty camera frame.")
      continue
    image = cv2.flip(image, 1)
    location = ((width-p_width)//2, 0)
    image = overlayImage(image, panel, location)
    image2 = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
    results = face_mesh.process(image2)
    if results.multi_face_landmarks != None:
      timer, p_idx = decrementTimer(timer, image, p_idx)
      panel = panels[p_idx]
      p_height, p_width = panel.shape[:2]
    else:
      timer = TIMER_INITIAL_VALUE          # reset timer
    # triming the image
    image = image[0:p_height,
                  location[0]:location[0]+p_width]
    cv2.imshow('Virtual Face-in-Hole Cutout', image)
    if cv2.waitKey(1) & 0xFF == ord('q'): break
cap.release()
cv2.destroyAllWindows()

特集2 自宅Linuxサーバー構築(Vol.88記載)

投稿日:2024.01.25 | カテゴリー: コード

著者:麻生 二郎

Linuxやサーバーソフト、インターネットの仕組みを知りたいのなら、Linuxサーバーを構築するのが一番です。使わなくなった古いノートパソコンを活用し、自宅内にLinuxサーバーを構築してみましょう。本特集では、その手順を分かりやすく紹介します。

シェルスクリプトマガジン Vol.88は以下のリンク先でご購入できます。

Part3 サーバーソフトを導入する

図1 Sambaの設定(/etc/samba/smb.conf)

[global]
workgroup = SHMAG
dos charset = CP932
unix charset = UTF8

[share]
path = /var/share
browsable = yes
writable = yes
create mask = 0777
directory mask = 0777

シェルスクリプトマガジンvol.88 Web掲載記事まとめ

投稿日:2024.01.25 | カテゴリー: コード

004 レポート Open Source Summit Japan開催
005 レポート 国内開発の日本語LLM
006 製品レビュー スマートテレビ「32S2」
007 NEWS FLASH
008 特集1 CentOS Linux 7からの移行先を考える/弦本春樹
013 Hello Nogyo!
014 特集2 自宅Linuxサーバー構築/麻生二郎 コード掲載
028 特別企画 ゆっくりMovieMaker4で映像制作 シナリオ作り編/ふる(FuruyamD)
038 Raspberry Pi Pico W/WHで始める電子工作/米田聡 コード掲載
042 大規模言語モデル/桑原滝弥、イケヤシロウ
044 Pythonあれこれ/飯尾淳 コード掲載
049 中小企業手作りIT化奮戦記/菅雄一
054 法林浩之のFIGHTING TALKS/法林浩之
056 タイ語から分かる現地生活/つじみき
062 香川大学SLPからお届け!/谷知紘
068 Linux定番エディタ入門/大津真
076 Techパズル/gori.sh
077 コラム「SELiunxとユニケージ」/シェル魔人

Vol.88

投稿日:2024.01.25 | カテゴリー: バックナンバー

 2024年6月末に「CentOS Linux 7」のサポートが終了します。CentOS Linuxは、無償のRed Hat Enterprise Linux(RHEL)互換Linuxディストリビューションで、多くの企業で利用されています。このような状況ですが、CentOS Linux 7の後継であるCentOS Linux 8はすでにサポートが終了し、現在CentOS Linuxの開発は行われていません。そのため、CentOS Linux 7の移行先を早急に考える必要があります。
 特集1では、CentOS Linux 7の移行先となる候補と、候補から移行先を選定するときのポイントを解説します。
 特集2では、自宅にLinuxサーバーを構築する方法を紹介します。数年前に比べ、クラウドサービスを利用すれば、個人でも簡単にLinuxサーバーを運用できます。よって、自宅にLinuxサーバーをわざわざ構築する意味はあまりありません。ただし、Linuxサーバー構築には、Linuxの基本操作、サーバーソフトの導入方法や使い方、インターネットの仕組み、セキュリティを含めたサーバーの運用管理方法など、ITに関する多くの知識が詰まっています。自宅にLinuxサーバーを構築してそれらの知識を身に付けましょう。
 特別企画は、動画投稿・共有サイト「YouTube」で人気の「ゆっくり実況」「ゆっくり解説」を作成できる無料動画編集ソフト「ゆっくりMovieMaker4」の第3弾(最終回)です。今回は、ストーリやシナリオの組み立て方、表示回数や視聴回数などのデータ分析など、人気が出る動画を制作するためのノウハウを解説します。
 このほか、連載の「Raspberry Pi Pico W/WHで始める電子工作」では日本語表示の湿温度計、「Pythonあれこれ」と「香川大学SLPからお届け!」ではそれぞれ、AI(人工知能)を使った顔検出とじゃんけんマシンを紹介します。
 今回も読み応え十分のシェルスクリプトマガジン Vol.88。お見逃しなく!

※記事掲載のコードはこちら。記事の補足情報はこちら

※読者アンケートはこちら

Vol.88 補足情報

投稿日:2024.01.25 | カテゴリー: コード

特集2 自宅Linuxサーバー構築

p.14の「Windows 10のサポートが終了する2024年6月末ごろ」は「Windows 10(バージョン22H2)のサポートが終了する2025年10月14日」の誤りです(詳しくサポート期間は、こちら)。お詫びして訂正いたします。

Windows 10(バージョン22H2)は、まだ1年半以上のサポートが受けられますので、安心してお使いください。

情報は随時更新致します。

  • shell-mag ブログの 2024年1月 のアーカイブを表示しています。

  • -->