OpenCVでスクリーンショット保存

こんにちは!
くろんです。

今回はOpenCVを使って画面のスクリーンショット画像を保存してみたいと思います。

まぁ、そこまで大変でもないので適当にコードとか載せていきます。

やること

1. WINAPIにてスクリーン情報取得
2. スクリーン情報より画面のピクセル情報を取る
3. OpenCVの画像フォーマットにピクセル情報を入れ込む

準備

- OpenCV準備(https://opencv.org/releases/からDL)
- 開発環境準備 -> VisualStudio2019使用
- 新規プロジェクト作成

OpenCVは今回、4.2.0を使用しました。

Windowsなら ↑ の赤枠からexe拾ってきて

展開フォルダ内のbuildから

bin\*.dll
include
x64\(VCバージョン)\*.lib

を自分のプロジェクトフォルダに持ってくると楽ですよ!

OpenCVを新規プロジェクトで使えるようにするためにはリンカーの設定を行います。

1. 新規プロジェクトを開き、「プロジェクト」タブ→「プロパティ」選択
2. 構成を「Release」に設定(Debugは同じく設定)
3. 「リンカー」→「全般」より「追加のライブラリディレクトリ」を選択
4. x64\(VCバージョン)\*.libより持ってきた*.libファイルがあるフォルダを選択
※opencv_world420.libとopencv_world420d.libというファイル名にdがついているものとそうでいないものがあると思うがこれらはRelease用かDebug用かで変わっている。dがついているものがDebug用

5. 「リンカー」→「入力」より「追加の依存ファイル」選択
6. 4.にて指定したフォルダに入っている*.libファイルをすべて依存ファイルとして指定
ex. Release用として設定していたら「 opencv_world420.lib」を追加

ついでにプロパティページにて「C/C++」内の「追加のインクルードディレクトリ」に includeフォルダを指定しておくと後で楽になります。

最後に動的ライブラリ(*.dll)を実行ファイルと同じ場所に置きます。
ビルドすると*.exeができるかと思うのでbin\*.dllをコピーします。

準備はこれでOKなはずです。

まとめ

- リンカーを設定
  - 追加のライブラリディレクトリ
  - 追加の依存ファイル
- 動的ライブラリ(*.dll)を実行ファイル(*.exe)と同じ場所に置く

コード書く

↓ 全体

HWND hwnd = GetDesktopWindow();
RECT rect;

GetWindowRect(hwnd, &rect);
unsigned int width, height;
width = rect.right;
height = rect.bottom;

BITMAPINFO bmpInfo;

bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpInfo.bmiHeader.biWidth = width;
bmpInfo.bmiHeader.biHeight = height;
bmpInfo.bmiHeader.biPlanes = 1;
bmpInfo.bmiHeader.biBitCount = 24;
bmpInfo.bmiHeader.biCompression = BI_RGB;

LPDWORD lpPixel;
HBITMAP hBitmap;
HDC hMemDC;
HDC hdc = GetDC(hwnd);
hBitmap = CreateDIBSection(hdc, &bmpInfo, DIB_RGB_COLORS, (void**)&lpPixel, NULL, 0);

hMemDC = CreateCompatibleDC(hdc);
SelectObject(hMemDC, hBitmap);

BitBlt(hMemDC, 0, 0, width, height, hdc, 0, 0, SRCCOPY);

cv::Mat bMat = cv::Mat(height, width, CV_8UC3);
bMat.data = (uchar*)lpPixel;

cv::Mat flipImage;
cv::flip(bMat, flipImage, 0);

cv::imwrite("test.jpg", flipImage);

まず

HWND hwnd = GetDesktopWindow();
RECT rect;

GetWindowRect(hwnd, &rect);
unsigned int width, height;
width = rect.right;
height = rect.bottom;

ここらへんでスクリーンの幅・高さとディスプレイのハンドルを取得します。

次に

BITMAPINFO bmpInfo;

bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpInfo.bmiHeader.biWidth = width;
bmpInfo.bmiHeader.biHeight = height;
bmpInfo.bmiHeader.biPlanes = 1;
bmpInfo.bmiHeader.biBitCount = 24;
bmpInfo.bmiHeader.biCompression = BI_RGB;

ここでBitmap形式で取得するときに必要な情報を設定します。(今回はOpenCVのMatフォーマットになるのでBitmap関係ないですがスクリーンの画素情報を取得するための儀式として書きます)

そして

LPDWORD lpPixel;
HBITMAP hBitmap;
HDC hMemDC;
HDC hdc = GetDC(hwnd);
hBitmap = CreateDIBSection(hdc, &bmpInfo, DIB_RGB_COLORS, (void**)&lpPixel, NULL, 0);

hMemDC = CreateCompatibleDC(hdc);
SelectObject(hMemDC, hBitmap);

Bitmap形式で画素を取得する準備を行います。

Bitmap形式でスクリーンの画素情報を取得するときにはBitBltを使用します。

BitBlt(hMemDC, 0, 0, width, height, hdc, 0, 0, SRCCOPY);

最後にOpenCVのMatフォーマットに入れ込みます

cv::Mat bMat = cv::Mat(height, width, CV_8UC3);
bMat.data = (uchar*)lpPixel;

cv::Mat flipImage;
cv::flip(bMat, flipImage, 0);

cv::imwrite("test.jpg", flipImage);

biBitCountで24(8bit3チャンネル)を指定していたのでMatフォーマットは CV_8UC3タイプを選択。

bMat.data はMatファイルの画素情報に当たる部分でそこにBitmap形式でスクリーン画素情報が入っている lpPixelの情報を入れています。

cv::flipで画像を上下反転しているのですがこれはデータの並びが逆なのでそのままだと反転して画像ができてしまうためです。

cv::imwriteは画像の保存をしてくれるOpenCVの関数です。

こんな感じにするとスクリーンショットをOpenCVのMatフォーマットにできます!!

※あっ、この方法だとディスプレイ設定で拡大表示とかして100%以外だとスクリーンの一部しか取得できない状態になるので気を付けてください。

↑ を回避するためにはもう少しごにょごにょやってあげる必要があります。

Geforce NOW 触ってみたよ!!

こんにちは!
くろんです。

今回は「GeForce NOW Powered by SoftBank」のCBTに参加できたので適当に体験した感想を書いていきます。
イベントページ https://cloudgaming.mb.softbank.jp/


導入

まず、準備から
必要なもの

- NVIDIAアカウント
- GeForce NOWアカウント
- ゲームプレイに必要なアカウント(Steam, Uplayなど)
- マシン(Mac/Win/Android)
 ※ 今回iPhoneは対象外

私は今回 Windowsにてプレイしました。

基本的には「GeForce NOW」アプリケーションをダウンロードして、
インストールするだけなので特に困る場面もなく進めることができました。

アプリケーションを起動するとこんな感じです 。

基本的な操作としてはプレイしたいゲームを検索窓より探し「プレイ」ボタンを押す、それだけ。

必要なアカウントログインしてゲームがプレイできるようになるのでとても簡単です。

Steamをプレイ?というか開いてSteamライブラリにあるゲームを選択してプレイすることもできましたが、
対応されていないゲームもあり、非対応ゲームを選択するとエラーがでます。

「GeForce NOW」でゲームをプレイする際にはゲームのインストールが必要になります。
ゲームはGeForce NOWのアプリケーションを閉じると、削除されるらしく毎回インストールが発生することになります。

ただ、インストールは100G超えているようなゲームでも5分程度で終了するので私としては許容範囲内ですね。

むしろ、昔やっていたゲームを久々にプレイしようとしてアプデが終わらず萎えてふて寝した経験があるので、これが起こらないだけでもやる価値があるかなと思います。
※ CBT段階なので人が増えたときにどうなるかはわかりません…
まぁ、10分以内にゲームが操作できる状態になれば許せますね。

ちなみに今回プレイした環境の回線速度はこんな感じです。

一応、公式のシステム要件が

こんな感じなので、回線速度に問題はないと思います。
他システム要件は高くないので省略します。


ゲームプレイ

今回は私が普段プレイしている「Rainbow six siege」で画質の比較します。

ゲーム内解像度は両方とも1920 x 1080にて画像を合わせています。
初めはSteam側のスクリーンショットで画像をとっていましたが、GeForce NOW側にてスクリーンショットでとった画像と実際に見る画像に違いがあったのでGeForce NOW側は [Shift + Win + S] で全体選択して画像をとりました。

GeForce NOWでSteamのスクリーンショットと実際の映像が違う問題は、ゲーム映像のストリーミングの問題でしょうね。

今回は上のようなことがあったので。
GeForce NOW
– プレイ画面のキャプチャー
ローカルマシン
– Steamのスクリーンショット
にてとった画像を使用します。

[上: GeForce NOW 下: ローカルマシン]

リスポーン地点

遠くのものが見えるか

スコープにて

画像だとこんな感じですね。
GeForce NOWだとFPSが60超える時があるが問題ないのか…(使用ディスプレイはリフレッシュレート60hz)

プレイしている感じだと映像の粗さを感じるのですが、画像にするとあまり変わらない感じですね…

ただ、プレイができないというほどの粗さでもないので、そういうのを気にしなければ問題なしですかね。
このままだと相手に負けたとき、言い訳で「粗くて見えなかった!!」って言うくらいには粗い印象なので今後に期待ですかね。

あと、気になったところといえば音でしょうか。
ネットが不安定になった時にプラグを刺しなおしたときみたいなブチッという音がして微妙に気になりましたね。

特に比較して書くこともなかったので適当にまとめて終わります。


まとめ

GeForce NOW
月額使用料(500円くらい)を払うことで自分が持っているゲームをクラウド上でプレイできる!!

メリット
  • ゲームのシステム要件を満たした実機を持っていなくてもプレイ可能
  • 起動時にアップデートでプレイできない心配がない
  • 自分のマシンの容量を気にする必要がない
  • ゲームインストールはまぁまぁ早い
デメリット
  • GeForce NOWを立ち上げるたびにゲームインストールするのが面倒
  • 画質が粗い
  • ノイズ音が入る
  • ゲーム以外にもお金がかかる

こんなところでしょうか。

ゲームがちゃんとできたので私としては好印象ですね。

デメリットは最初から分かっていたようなものなので、技術の進歩に期待したいところですね。

非対応タイトルの対応やPS4、Switchゲームへの対応も発展していけば考えられるかと思うので、温かい目で見守っていきますかね!

まぁ、自分がすでに持っているゲームに月額+500円払ってまでやりたいかというと微妙ですけどね!!

では

2020ワンフェス(冬)行ってきました!

こんにちは!
くろんです!

また、1日1記事をさぼってました。

一度、さぼり始めると止まらねぇですね!

今回は技術的な話も思いつかないので、趣味の話を書きます。

皆さんはワンフェスというイベントをご存じですか?

ワンフェスとは平たく言うと模型版コミケって感じです。
詳しくは https://wonfes.jp/knowledge/about/

今回はそこに行ってきましたー。
ってことを書こうかと思います。

まぁ、イベントに行く目的は人それぞれいくつかありますが私の目的はいつもこんな感じです。

  • 同人のガレージキットが欲しい!
  • 企業の新商品情報が欲しい!
  • 新商品の造形を生で見たい!
  • イベントの空気を感じたい!

です!

今回は買い物メインではなかったので、ゆったり10時に幕張メッセに行きました!
(10時ぐらいに行くのが一番楽でいいですね…早起きつらい)

以下、今回見てきたもの

コトブキヤ新商品展示

マガツキのお披露目、これは気合入ってますわ。

メガミデバイス・武装神姫コラボ情報とスサノオ展示。
トークショーにてメガミデバイスベースで武装神姫のMMS素体っぽさを出すためのこだわりの話をしていて、これは期待できる感じがしましたー
まぁ、色々大変そうでもありましたが…

あとは、バレットナイツシリーズの新作です。
バレットナイツシリーズだから以前の金型が使いまわせると思いきや、
こだわった結果、新規金型が増えていく話は笑ってしまった。

もう、1つくらいあった気がしましたが写真を撮り忘れてしまったので…

メガハウス

デスクトップアーミー!!

わけがわからなくなるくらいコラボしまくってます。

気になったもの

ボークスから発売されるメイドインアビスのプルシュカ!

めっちゃしっかり作ってある、流石ボークス!!

フレアにてオーディンスフィア モーリス出張レストランの展示!

それぞれのキャラクターがめっちゃ可愛い、しかもオーディンスフィアの世界観がそのままな感じがすごい。

販売されたら買いたいけどいつ出るのかなー

気になったものは以上!!

最後に感想

「今年、お財布絶対やばい!!」

では!

お片付けの様子