火曜日, 3月 12, 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
画像を処理する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を偽装する方法を記しておきます。
意外と簡単な話で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エラーも怖くないですね☆