火曜日, 3月 12, 2024

【google_ml_kit】flutterでcameraimageからinputimageに変換する方法【2024年版】

google_ml_kitを使って画像認識の処理をするときにカメラからの画像データはCameraImageで渡されますがInputImageに変換する必要があります。CameraImageからInputImageに変換する方法を書いた記事はインターネット上にそこそこありますが、変換に使うライブラリの一つであるgoogle_mlkit_commonsが0.4.0から大規模な変更があったためほとんどのコードがコピペでは使えません。
https://pub.dev/pack … it_commons/changelog
そのため、最新のgoogle_mlkit_commonsに合わせた変換のコードを書いてみたので好きにコピペするなりしてください

pubspec.yaml

camera: ^0.10.5+9
google_ml_kit: ^0.16.3
google_mlkit_commons: ^0.6.1
import 'dart:async';
import 'package:camera/camera.dart';
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:google_ml_kit/google_ml_kit.dart';

Future<InputImage> convertCameraImageToInputImage(
    CameraImage cameraImage, CameraDescription camera) async {
  final WriteBuffer allBytes = WriteBuffer();
  for (final Plane plane in cameraImage.planes) {
    allBytes.putUint8List(plane.bytes);
  }
  final bytes = allBytes.done().buffer.asUint8List();

  final Size imageSize =
      Size(cameraImage.width.toDouble(), cameraImage.height.toDouble());
  final camera = widget.cameras.firstWhere(
    (camera) => camera.lensDirection == CameraLensDirection.front,
  );
  final InputImageRotation imageRotation =
      _rotationIntToImageRotation(camera.sensorOrientation);

  final InputImageFormat inputImageFormat =
      InputImageFormatValue.fromRawValue(cameraImage.format.raw) ??
          InputImageFormat.nv21;
  final inputImageData = InputImageMetadata(
    size: imageSize,
    rotation: imageRotation,
    format: inputImageFormat,
    bytesPerRow: cameraImage.planes[0].bytesPerRow,
  );
  final result = InputImage.fromBytes(bytes: bytes, metadata: inputImageData);
  return result;
}

InputImageRotation _rotationIntToImageRotation(int rotation) {
  switch (rotation) {
    case 0:
      return InputImageRotation.rotation0deg;
    case 90:
      return InputImageRotation.rotation90deg;
    case 180:
      return InputImageRotation.rotation180deg;
    case 270:
      return InputImageRotation.rotation270deg;
  }
  return InputImageRotation.rotation0deg;
}

水曜日, 2月 23, 2022

【python】1番手軽な画像収集方法【webスクレイピング】【画像収集】【データセット】

画像を処理するAIのデータセットなどで画像を収集しなければならない時が時々ありますよね。
みなさんは画像収集する時どのようにして集めていますか?webスクレイピングの有名な手段としては、

  • selenium
  • Beautiful Soup
  • Requests
  • Scrapy

などがあると思いますが、画像収集という点だけに絞れば、もっと手軽に試せる手段があります。それがicrawlerです。

icrawlerとは

ウェブクローラ用のライブラリで画像や動画をスクレイピングすることができます。

使い方

まず、pipでicrawlerをインストールします。(既にインストールしている人はスキップしてください。)ターミナルやコマンドプロンプトなどで

pip install icrawler

です。
次に、インポートします。現在、icrawlerが機能する検索エンジンはbaidu・bingのみです。googleも対応していたようですが、現在は対策されたためエラーが出て使えません。日本人がbaiduを使うときはよっぽどないと思いますのでbingを使うという体で進めていきます。bingを使うときのicrawlerをインポートするコードは

from icrawler.builtin import BingImageCrawler

です。

crawler = BingImageCrawler(downloader_threads=4,storage={"root_dir": "apple"})

このコードはどの検索エンジンで何スレッドでクロールし、その結果をどこに保存するか決めています。このコードではbingで4スレッドでクロールをし、結果をappleというフォルダに入れるという設定になっています。

crawler.crawl(keyword="りんご", max_num=10)

このコードはどんなワードで検索し、その画像を何個保存するのかを決めています。このコードはりんごというキーワードで検索し、出てきた画像を10個保存するということになっています。

まとめ

これらをまとめると

from icrawler.builtin import BingImageCrawler
crawler = BingImageCrawler(downloader_threads=4,storage={"root_dir": "apple"})
crawler.crawl(keyword="りんご", max_num=10)

となります。Requestsなどで書くよりも遥かに短いです。手軽なので、試してみてエラーが出て動かないとなってから変えてみても遅くないというのがメリットだと思います。しかし、ここまで書いておきながら時間があるのであれば他のライブラリは圧倒的に汎用性が高いので画像のクロールを通してseleniumやRequestsなどの他のライブラリに慣れておくというのは悪くないのかも・・・とも思ってしまいました。

月曜日, 3月 22, 2021

seleniumで簡単にreferer偽装[python](403エラーやアクセス禁止された時に)

seleniumでアクセスしようとした時にどこからアクセスしたかで判別されて弾かれることがあります。

そんな時にrefererを偽装する方法を記しておきます。

意外と簡単な話でseleniumはjavascriptのコードを実行することができるため、javascriptを駆使します。
その前にまずはrefererとして設定したいサイトにアクセスします。

chrome_options = Options()
driver = webdriver.Chrome("/*chromeドライバーのパス*/", chrome_options=chrome_options)
driver.get("/*refererとして設定したいサイトのurl*/")

そしてseleniumにはjavascriptを実行するapiが存在します。

driver.execute_script(/*ここにjavascriptのコードを書く*/)

がjavascriptを実行するapiです。
ここのjavascriptに要素を書き換える命令を使って

なにかしらの要素をaタグに書き換えます。

そうです。自分が指定したurlにアクセスし、htmlの要素を書き換えてリンクを作成し、クリックしてそのサイトにアクセスすればrefererは自分で決めることができます。
そして下記のコードをサイトに合わせて書き換えて実行します。

var refererselector=document.getElementById("/*なにかしらのhtmlの要素のid*/");
refererselector.innerHTML="<a id='refererurllink' href=''+str(imgurl)+''>吹っ飛べ!</a>"

そしてseleniumのapiでクリックします。

element=driver.find_element_by_id("refererselector")
element.click()

これらを一つのpythonのプログラムにまとめると下記のようになります。

driver.execute_script('var refererselector=document.getElementById("/*なにかしらのhtmlの要素のid*/");refererselector.innerHTML="<a id='refererurllink' href=''+str(imgurl)+''>吹っ飛べ!</a>"')
element=driver.find_element_by_id("refererurllink")
element.click()

いかがだったでしょうか?
これで403エラーも怖くないですね☆

管理者用

Menu

色々あってメモ帳がわりのブログ的なものを作ることになりましたが、wordpressアレルギーなるものが発病したので代わりにflatpressという物を使って作ってみました。

プログラム関連のことを書いていこうと思っています。

ちなみに作った物やwebサイトはここに置いています。

flatpressの初期のテーマがどうしても気に入らなくて色々探しているうちに何が何だかわからなくなって、

ブログにふさわしいテーマってなんだ?

と自問自答しているうちに結局デフォルトのものに近い物を使ってしまった。
なんかいいテーマないですかね?

About

shimaumaと名乗っています。
なんとなく趣味でプログラムを書いてみたりしている人です。
phpから初めてpythonに手を出してその後にc#に手を出して、やめてpythonに戻ってきました。
ついったー
@shimauma4444