粒子であり、波である。
その位置を計測すると粒子で計測され、波の状態ではなくなる。
納得のいく説明を見つけた。
波であることを確認するためには、時間が必要(周波数があるため)である。波を止めなければ位置を確認できないが、止めると周波数(波)がわからなくなる。で、周波数と位置を同時に確定することができない。
なるほど。ちょっと、、、電子は1つの粒がくねくね動いている訳ではないらしいので、このような理解は誤解なのかもしれない。
つぶつぶがくねくねしているのではなく、1粒のエネルギーが波の特性で移動しているという、、、、例えば 4次元の物体を3次元から見るとそのように見えるのかもしれないね。この世は4次元、、、多次元で、その影が3次元に写っているのを観察するからうまく捉えることができないのではないでしょうか。
真空を伝わってくるというのも別次元にある物体(なんだろ)であれば、3次元では真空でも別の次元では真空でないかもしれないし。
電場や磁場はそれぞれ次元が違うのかもしれない。電場と磁場は3次元から見ると直交しているように見えるのかもしれないな。
超弦理論に影響されたかな。
プログラまのメモ simple source code
simple source code for linux. simple question & answers. simple testing tools.
2016年8月16日火曜日
2016年8月15日月曜日
ASUS C100PA Flip クロームブックを試す 続き1
これもクロームブックから書いています。Androidよりも快適に使えます。クロームブックはキーボードが付いているので、ノートPCレベルでブログが書けます。
前回のDev版は不都合が多かったので、ベータにしておいたのですが、久しぶりにDev版を使ってみたら、以前のような途中で変なことになるバグがなくなっていました。
Androidアプリは普通に使えるようになっていました。もちろん、機種限定や機能限定されているものは動かないもの、インストールできないものがあります。
近頃の使い方が固定化されてきたので、、、、、
まず、ノートPCの持ち歩きは極端に減りました。普通の打ち合わせには、クロームブックだけで十分となりました。WiFiポケットルーターをMVNOで持ち歩けば、ノートPCは不要です。ノートPCの持つ情報の半分程度はgoogledriveに入っています。ですので、クロームブックでも参照できます。
ノートPCでのみ管理している(バックアップはありますが、、)データに関してはクロームブックでは開けないファイルがいつくかあります。これらを打ち合わせ先(客先)などから開く方法として、リモートデスクトップがあります。これで参照は簡単にできますし、ノートPCで実行させて、メールやDropbox経由でクロームブックに取り込むということもできます。
唯一できないのが、ノートPCとUSB経由で繋がる特殊な機器とはクロームブックは通信できません。クロームブックのUSBドライバが限定されているためで、Androidでサポート対象となれば、可能となるかもしれません。当分の間はこのような特殊な機器と接続する予定のある場合の客先ではノートPCを持っていくことになります。
実際、打ち合わせの95%はクロームブックだけげ事が足りるようになりました。
ここ1ヶ月くらいのDev版は落ち着いているようですし。
AndroidAppsのベータ版対応が待ち遠しいです。
前回のDev版は不都合が多かったので、ベータにしておいたのですが、久しぶりにDev版を使ってみたら、以前のような途中で変なことになるバグがなくなっていました。
Androidアプリは普通に使えるようになっていました。もちろん、機種限定や機能限定されているものは動かないもの、インストールできないものがあります。
近頃の使い方が固定化されてきたので、、、、、
まず、ノートPCの持ち歩きは極端に減りました。普通の打ち合わせには、クロームブックだけで十分となりました。WiFiポケットルーターをMVNOで持ち歩けば、ノートPCは不要です。ノートPCの持つ情報の半分程度はgoogledriveに入っています。ですので、クロームブックでも参照できます。
ノートPCでのみ管理している(バックアップはありますが、、)データに関してはクロームブックでは開けないファイルがいつくかあります。これらを打ち合わせ先(客先)などから開く方法として、リモートデスクトップがあります。これで参照は簡単にできますし、ノートPCで実行させて、メールやDropbox経由でクロームブックに取り込むということもできます。
唯一できないのが、ノートPCとUSB経由で繋がる特殊な機器とはクロームブックは通信できません。クロームブックのUSBドライバが限定されているためで、Androidでサポート対象となれば、可能となるかもしれません。当分の間はこのような特殊な機器と接続する予定のある場合の客先ではノートPCを持っていくことになります。
実際、打ち合わせの95%はクロームブックだけげ事が足りるようになりました。
ここ1ヶ月くらいのDev版は落ち着いているようですし。
AndroidAppsのベータ版対応が待ち遠しいです。
2016年6月20日月曜日
ASUS C100PA Flip クロームブックを試す
購入
あるニュースを見て購入を決定した。
アンドロイドアプリが動作するということだ。
正式版(stable版)の機能ではないのだが、開発版(Dev版)に設定を変更すればアンドロイドのアプリストアが現れ、ダウンロードと実行ができるようになるらしい。
購入した。2016/06/18。
設定
まずは、アプリストアを表示させるために、googleアカウントでログインして、ChromeBookの設定でDev版に変更、最新をダウンロードさせる(手動でも可能、自動でも時間が経てば更新される)。
再起動した。
おぉっ アプリストアが現れた。
適当なところでMicrosoftOfficeのWord、Excelを。問題ないようだ。
アプリストアで『該当端末で動作しません』と出たらもちろんダメです。
自作のアプリのapkを入れようとしたが、メール添付でapkを見せても、GoogleDrive経由で見せても、インストールはできない。インストール開始するとエラーになる。セキュリティ上ダメですと言われる。アプリストア以外からのインストールは難しいようです。自作アプリは開発途中だったのですが、アプリストアにアップして、アルファ版テスト(クローズメンバー)で公開すればダウンロードできるようになりました。
C言語で作ったライブラリ付きのアプリでしたが、問題なく動作しました。ただし、
ファイルを開く操作すると落ちました。この自作アプリはアンドロイド共通のファイルダイアログを使っていました。そして、GoogleDriveは本体(chromebook)が持っているので動作するだろうと思っていましたが、動作しません。またファイルダイアログでちょっと変わった操作をすると、アプリケーションエラーで落ちていました。結局、GoogleDriveのアンドロイドアプリ版をインストールしたら治りました。当たり前か。
モバイルで使うために、WiFiルータにWiFi接続を変更しようとしたら、画面が真っ黒になってリブートされます。リブート後も同じでした。Dev版だからなのかよく分かりませんでしたが、そんなバグが残ったままDev版をリリースするとは思えなかったので、設定画面からSSIDを指定して操作するとつながりました。右下のWiFi一覧から切り替えようとするとBlackOutしていました。一旦SSIDとパスワードを覚えてくれたら、あとは自由に切り替わるので問題ありません。
のこりはchromeのリモートデスクトップを使ってみることです。これがまともに使えるなら、PCは社内に残しておいて、chromebookだけを持って仕事ができます。
本当にできるのかな。
結果は別の日にレポートします。
あるニュースを見て購入を決定した。
アンドロイドアプリが動作するということだ。
正式版(stable版)の機能ではないのだが、開発版(Dev版)に設定を変更すればアンドロイドのアプリストアが現れ、ダウンロードと実行ができるようになるらしい。
購入した。2016/06/18。
設定
まずは、アプリストアを表示させるために、googleアカウントでログインして、ChromeBookの設定でDev版に変更、最新をダウンロードさせる(手動でも可能、自動でも時間が経てば更新される)。
再起動した。
おぉっ アプリストアが現れた。
適当なところでMicrosoftOfficeのWord、Excelを。問題ないようだ。
アプリストアで『該当端末で動作しません』と出たらもちろんダメです。
自作のアプリのapkを入れようとしたが、メール添付でapkを見せても、GoogleDrive経由で見せても、インストールはできない。インストール開始するとエラーになる。セキュリティ上ダメですと言われる。アプリストア以外からのインストールは難しいようです。自作アプリは開発途中だったのですが、アプリストアにアップして、アルファ版テスト(クローズメンバー)で公開すればダウンロードできるようになりました。
C言語で作ったライブラリ付きのアプリでしたが、問題なく動作しました。ただし、
ファイルを開く操作すると落ちました。この自作アプリはアンドロイド共通のファイルダイアログを使っていました。そして、GoogleDriveは本体(chromebook)が持っているので動作するだろうと思っていましたが、動作しません。またファイルダイアログでちょっと変わった操作をすると、アプリケーションエラーで落ちていました。結局、GoogleDriveのアンドロイドアプリ版をインストールしたら治りました。当たり前か。
モバイルで使うために、WiFiルータにWiFi接続を変更しようとしたら、画面が真っ黒になってリブートされます。リブート後も同じでした。Dev版だからなのかよく分かりませんでしたが、そんなバグが残ったままDev版をリリースするとは思えなかったので、設定画面からSSIDを指定して操作するとつながりました。右下のWiFi一覧から切り替えようとするとBlackOutしていました。一旦SSIDとパスワードを覚えてくれたら、あとは自由に切り替わるので問題ありません。
のこりはchromeのリモートデスクトップを使ってみることです。これがまともに使えるなら、PCは社内に残しておいて、chromebookだけを持って仕事ができます。
本当にできるのかな。
結果は別の日にレポートします。
2016年5月3日火曜日
MFC オートコンプリートというより選択リストから選択できるように。
エディットコントロールにコンボボックスのようにリストボックスをつけて、エディットの入力内容に基づいて選択候補を表示するというものが欲しかった。コンボボックスではどうしても操作がおかしくなるので実現できなかった。IAutoCompleteは訳がわからない。フィルターを切っても、内部で訳の解らないフィルターをされるので、自由に表示できず、全く使えなかった。
単純にこちらで指定した文字列群を表示して選択ができるだけのインタフェースが見つからなかった。
で、作成してみた。
FindCommnetsは自作の選択項目の検索モジュールです。ここのstraryFがリストに表示されるという塩梅です。
単純にこちらで指定した文字列群を表示して選択ができるだけのインタフェースが見つからなかった。
で、作成してみた。
クラス名:AcEdit これ自体にリストボックスを持たせてある。
AcEdit.h
-------------------------------
#pragma once
#include "afxcoll.h"
#include "PopupListBox.h"
// AcEdit
class AcEdit : public CEdit
{
DECLARE_DYNAMIC(AcEdit)
public:
AcEdit();
virtual ~AcEdit();
protected:
DECLARE_MESSAGE_MAP()
public:
private:
// リストボックスITEM
CStringArray m_straryListItem;
public:
// ボップアップ
CPopupListBox *m_pPopListBox; // これがポップアップリストボックスダイアログ
void ResetContent();
void AddString(LPCTSTR lpszString);
void ShowDropDown(bool bShow);
afx_msg LRESULT OnUserSelChange(WPARAM wParam, LPARAM lParam);
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
void Moved();
};
-----------------------------------------
AcEdit.cpp
-----------------------------------------
// AcEdit.cpp : 実装ファイル
//
#include "stdafx.h"
#include "APPLICATION.h" ダイアログのため。
#include "AcEdit.h"
// AcEdit
IMPLEMENT_DYNAMIC(AcEdit, CEdit)
AcEdit::AcEdit()
{
this->m_straryListItem.SetSize(0, 1500);
this->m_pPopListBox = new CPopupListBox();
}
AcEdit::~AcEdit()
{
delete m_pPopListBox;
m_pPopListBox = NULL;
}
BEGIN_MESSAGE_MAP(AcEdit, CEdit)
ON_MESSAGE(WM_USER_SEL_CHANGE, OnUserSelChange)
ON_WM_KEYDOWN()
END_MESSAGE_MAP()
// AcEdit メッセージ ハンドラー
void AcEdit::ResetContent()
{
if (!::IsWindow(m_pPopListBox->m_hWnd))
{
m_pPopListBox->Create(this);
}
m_pPopListBox->RemoveString();
ShowDropDown(false);
}
void AcEdit::AddString(LPCTSTR lpszString)
{
if (!::IsWindow(m_pPopListBox->m_hWnd))
{
m_pPopListBox->Create(this);
}
m_pPopListBox->AddString(lpszString);
}
void AcEdit::ShowDropDown(bool bShow)
{
if ((m_pPopListBox) && (::IsWindow(m_pPopListBox->m_hWnd)))
{
if (bShow)
{
m_pPopListBox->ShowWindow(SW_SHOWNA);
}
else
{
m_pPopListBox->ShowWindow(SW_HIDE);
}
}
}
LRESULT AcEdit::OnUserSelChange(WPARAM wParam, LPARAM lParam)
{
/// list選択した通知
CString strA;
m_pPopListBox->GetCurSelString(strA);
this->SetWindowTextA(strA);
this->SetFocus();
return 0L;
}
void AcEdit::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if ((nChar == VK_UP) || (nChar == VK_DOWN) || (nChar == VK_TAB))
{
if (m_pPopListBox)
{
m_pPopListBox->StartSel();
}
}
CEdit::OnKeyDown(nChar, nRepCnt, nFlags);
}
void AcEdit::Moved()
{
if (m_pPopListBox)
m_pPopListBox->Reshow();
}
-----------------------------------------------------
popuplistbox.h
-----------------------------------------------------
#pragma once
#include "afxwin.h"
// CPopupListBox ダイアログ
#define WM_USER_SEL_CHANGE (WM_USER + 0x601)
class CPopupListBox : public CDialogEx
{
DECLARE_DYNAMIC(CPopupListBox)
public:
CPopupListBox(CWnd* pParent = NULL); // 標準コンストラクター
virtual ~CPopupListBox();
// ダイアログ データ
enum { IDD = IDD_LISTBOX };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV サポート
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnNcDestroy();
virtual void OnOK();
virtual void OnCancel();
// データ表示用
CListBox m_listBox;
afx_msg void OnLbnSelchangeListAc();
int AddString(LPCTSTR lpszString);
// 登録文字列を削除
void RemoveString();
// 選択中の文字を取得する。
int GetCurSelString(CString & strSelString);
void Create(CWnd *pWnd);
CWnd *m_pWnd;
void StartSel();
void Reshow();
afx_msg void OnLbnDblclkListAc();
};
----------------------------------------------
popuplistbox.cpp
----------------------------------------------
// PopupListBox.cpp : 実装ファイル
//
#include "stdafx.h"
#include "APPLICATION.h" // リソースのため
#include "PopupListBox.h"
#include "afxdialogex.h"
// CPopupListBox ダイアログ
IMPLEMENT_DYNAMIC(CPopupListBox, CDialogEx)
CPopupListBox::CPopupListBox(CWnd* pParent /*=NULL*/)
: CDialogEx(CPopupListBox::IDD, pParent)
{
m_pWnd = NULL;
}
CPopupListBox::~CPopupListBox()
{
}
void CPopupListBox::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_LIST_AC, m_listBox);
}
BEGIN_MESSAGE_MAP(CPopupListBox, CDialogEx)
ON_WM_NCDESTROY()
ON_LBN_SELCHANGE(IDC_LIST_AC, &CPopupListBox::OnLbnSelchangeListAc)
ON_LBN_DBLCLK(IDC_LIST_AC, &CPopupListBox::OnLbnDblclkListAc)
END_MESSAGE_MAP()
// CPopupListBox メッセージ ハンドラー
void CPopupListBox::OnOK()
{
// TODO: ここに特定なコードを追加するか、もしくは基底クラスを呼び出してください。
// CDialogEx::OnOK();
if (m_pWnd)
m_pWnd->PostMessageA(WM_USER_SEL_CHANGE);
}
void CPopupListBox::OnCancel()
{
// TODO: ここに特定なコードを追加するか、もしくは基底クラスを呼び出してください。
// CDialogEx::OnCancel();
}
int CPopupListBox::AddString(LPCTSTR lpszString)
{
if (IsWindowEnabled())
{
int ret = m_listBox.AddString(lpszString);
CRect rect1;
m_listBox.GetWindowRect(rect1);
int nW = rect1.Width();
CDC *pDC = m_listBox.GetDC();
CSize size1 = pDC->GetTextExtent(lpszString);
ReleaseDC(pDC);
if (size1.cx > nW)
nW = size1.cx; // 最大の値とする。
int nH = 0;
if (m_listBox.GetCount() > 20)
{
nH = m_listBox.GetItemHeight(0) * 20 + 6;
nW += 24; // ScrollBar
}
else
{
nH = m_listBox.GetItemHeight(0) * m_listBox.GetCount() + 6;
}
rect1.bottom = rect1.top + nH;
rect1.right = rect1.left + nW;
this->MoveWindow(rect1);
ScreenToClient(rect1);
m_listBox.MoveWindow(rect1);
return ret;
}
return -1;
}
// 登録文字列を削除
void CPopupListBox::RemoveString()
{
if (IsWindowEnabled())
{
CRect rect1;
m_listBox.GetWindowRect(rect1);
ScreenToClient(rect1);
rect1.right = rect1.left + 60;
m_listBox.MoveWindow(rect1);
this->m_listBox.ResetContent();
}
}
// 選択中の文字を取得する。
int CPopupListBox::GetCurSelString(CString & strSelString)
{
int nIdx = 0;
if (IsWindowEnabled())
{
nIdx = m_listBox.GetCurSel();
if (nIdx >= 0)
{
m_listBox.GetText(nIdx, strSelString);
}
}
return nIdx;
}
void CPopupListBox::Create(CWnd *pWnd)
{
CDialog::Create(IDD, pWnd);
m_pWnd = pWnd; // 呼び出し元
Reshow();
m_pWnd->SetFocus();
}
void CPopupListBox::Reshow()
{
CRect rect1;
if (m_pWnd && ::IsWindow(m_pWnd->m_hWnd))
{
m_pWnd->GetWindowRect(rect1);
this->SetWindowPos(NULL, rect1.left, rect1.bottom, 0, 0, SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSIZE);
}
}
void CPopupListBox::StartSel()
{
m_listBox.SetFocus();
this->m_listBox.SetCurSel(0);
}
void CPopupListBox::OnLbnDblclkListAc()
{
if (m_pWnd)
m_pWnd->PostMessageA(WM_USER_SEL_CHANGE);
}
----------------------------------------------------
Dialog定義
----------------------------------------------------
IDD_LISTBOX DIALOGEX 0, 0, 139, 9
STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_SYSMENU
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
LISTBOX IDC_LIST_AC,0,0,138,9,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
END
MFC経験者ならそれなりに理解できると思います。リストボックスの横幅の処理がまずいですが、なんとかなるでしょ。
勝手に修正してください。
ダイアログ以外でなんとかしようと思ったのですが、、、使えるものが見当たらないので、自作です。
上位のダイアログエディタで、EditBoxを配置した後、変数追加でAcEditクラスの変数 m_edtFind として追加します。
AcEditの通知関数は、EN_CHANGEを追加して、下記のように。
.....
ON_EN_CHANGE(IDC_EDIT_FIND_R, &CDFindNext::OnEnChangeEditFindR)
.....
void CDFindNext::OnEnChangeEditFindR()
{
CString strA;
this->m_edtFind.GetWindowTextA(strA);
if (strA.GetLength())
{
char cC = strA.GetAt(0);
if ((cC >= '0') && (cC <= '9'))
this->m_btnOK.SetWindowTextA("Go");
else
this->m_btnOK.SetWindowTextA("検索");
m_bFirst = true;
SetStrings();
SetTimer(TM_IDX_DROPDOWN, 500, NULL);
}
else
{
m_edtFind.ShowDropDown(false); // 消す
}
}
void CDFindNext::SetStrings(void)
{
CStringArray straryF;
straryF.SetSize(0, 1500);
CString strA;
m_edtFind.GetWindowTextA(strA);
if (strA.GetLength())
{
if (((CMainFrame *)AfxGetMainWnd())->FindComments(strA, straryF))
{
m_edtFind.ResetContent(); ///リストボックス文字列を消します。
for (int i = 0; i < straryF.GetCount(); i++)
{
CString strAA = straryF.GetAt(i);
strAA.Trim();
m_edtFind.AddString(strAA);/// 文字列セット
}
m_edtFind.ShowDropDown(true); //// 表示指令
}
}
}
ここまで書けばなんとかなるでしょ。
作ったばかりですが、大きな問題はなさそうですのでUPしました。
細かいところは自分で修正してください。
余計な定義が残っているかもしれません。よろしく対処してください。FindCommnetsは自作の選択項目の検索モジュールです。ここのstraryFがリストに表示されるという塩梅です。
2016年4月10日日曜日
Windows10 OneDriveの設定変更
デスクトップモードにする。
タスクバーの右端にあるOneDriveアイコン(なければ隠れているので、▲を押して表示する)を押す。
設定を選ぶ。
出てくるダイアログの設定を選んで、設定しなおす。
Okを押す。
反映するためにWindowsを再起動する。
疑問点:タブレットモードでは設定変更できないのは何故か。結局、デスクトップモードが必要になるということ。結局はキーボードとマウスが必要になるということだ。
タスクバーの右端にあるOneDriveアイコン(なければ隠れているので、▲を押して表示する)を押す。
設定を選ぶ。
出てくるダイアログの設定を選んで、設定しなおす。
Okを押す。
反映するためにWindowsを再起動する。
疑問点:タブレットモードでは設定変更できないのは何故か。結局、デスクトップモードが必要になるということ。結局はキーボードとマウスが必要になるということだ。
2016年4月3日日曜日
ONDA V891を試す Windows10
一昨日、ONDA V891を購入。DualBootもあったが、Windowsのみで購入。
格安Windows10タブレットがどの程度のものかを調べるためである。
・インストール
元は中国製で中国国内で利用するためにセットアップされているものを
日本語パッチを入れて、設定を日本語にすることで、日本語で使おうと
いう代物である。
添付されていた説明書の通りに、設定し(既に設定されていても、もう一度
選択し直して)、再起動なども説明書通りに行う。
サインアウトしないと設定変更できない項目が多いようで、兎に角、再起動
させることが大事である。あと、日付を現時点に修正すること。
私の場合は1日待った時点で最新のWindows10に更新された。この更新で
日本語化が完了した。音声認識なども全て日本語になった。
・使ってみた
少々重いなと感じた。
タッチの反応も少し遅いような気もするが、この程度なら十分だ。
電池の持ちが悪いような気がするが、気のせいかもしれない。
カメラは、これで何かを撮って誰かに見せようとは思わない。ガラケーか。
Cortanaもピンとこない。装備のマイクでは調整できないらしい。調整の問題?
結論:
悪くは無いがもう少し使い込まないと判らない。
Windows10はDesktopのOSだとつくづく感じる。
==> MSはタブレットに手を出さないでほしい
Windows7の組込バージョンよりはずっと高速。
高速化しているので安定感がある。
低廉だけどインテリジェンスな計測器アプリを作れるかなと。
テザリングはスマホに任せる。
据え付けるのは向かないと思う。
機器のタッチパネルの代わりになるかな。
格安Windows10タブレットがどの程度のものかを調べるためである。
・インストール
元は中国製で中国国内で利用するためにセットアップされているものを
日本語パッチを入れて、設定を日本語にすることで、日本語で使おうと
いう代物である。
添付されていた説明書の通りに、設定し(既に設定されていても、もう一度
選択し直して)、再起動なども説明書通りに行う。
サインアウトしないと設定変更できない項目が多いようで、兎に角、再起動
させることが大事である。あと、日付を現時点に修正すること。
私の場合は1日待った時点で最新のWindows10に更新された。この更新で
日本語化が完了した。音声認識なども全て日本語になった。
・使ってみた
少々重いなと感じた。
タッチの反応も少し遅いような気もするが、この程度なら十分だ。
電池の持ちが悪いような気がするが、気のせいかもしれない。
カメラは、これで何かを撮って誰かに見せようとは思わない。ガラケーか。
Cortanaもピンとこない。装備のマイクでは調整できないらしい。調整の問題?
結論:
悪くは無いがもう少し使い込まないと判らない。
Windows10はDesktopのOSだとつくづく感じる。
==> MSはタブレットに手を出さないでほしい
Windows7の組込バージョンよりはずっと高速。
高速化しているので安定感がある。
低廉だけどインテリジェンスな計測器アプリを作れるかなと。
テザリングはスマホに任せる。
据え付けるのは向かないと思う。
機器のタッチパネルの代わりになるかな。
2016年3月22日火曜日
MFC、opencv、USBカメラ
机の上でテストした基板の状態などの写真を簡単に撮影して、結果報告や資料として纏めておきたいということで、USBカメラをPCに接続して簡単に写真が撮れないかと。opencvを使うと簡単にできるらしいということで。
既知の人には今さら何を言ってるんだろうと思われるかもしれないけど。とりあえず。
まず、USBカメラは、、、
既知の人には今さら何を言ってるんだろうと思われるかもしれないけど。とりあえず。
まず、USBカメラは、、、
ELECOM WEBカメラ 200万画素 1/4インチCMOSセンサ ガラスレンズ搭載 筒型 イヤホンマイク付 ブラック UCAM-DLA200HBK
を選択。amazonで3千円、少し古い型のようだけど、ガラスレンズだということで決めた。
VisualStudio2013、MFCにて簡単なシャッターを押すだけのモニタを作る。
まず、適当なダイアログプロジェクトを作る。
そのプロジェクトにopencvを参照させるには、ツールメニューのNugetパッケージマネージャー、ソリューションのNugetパッケージの管理を開く。
右上の オンラインの検索 に opencvと入れて検索させる。
たぶん先頭に出てくる OpenCV OpenCV is a library of programming for realtime computer vision.のインストール釦を押す。
これでopencvが使えるようになる。
-------------------
stdafx.h
-------------------
stdafx.h
-------------------
#include <opencv2/core/core.hpp>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
を追加する。
#include <opencv2/core/core.hpp>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
を追加する。
大体下記のソースを参照して貰えば、概要は分かると思います。実際はスレッドを起こして実行しています。
cv::VideoCapture(int カメラ番号)この番号はPCに接続しているカメラの番号なので、0から始まる。私の場合はノートPCにカメラが既に付いているので1が外付けのカメラだった。OSが認識する順なので、立ち上げ時に繋いでいると順序が入れ替わる可能性がある。結構不便。
cv::Mat これにイメージが取り込まれる。cam >> cam1image
cv::imwrite()、ファイル名の拡張子でJPGだったりPNGなどを指定できる。
CvvImageはDCとの仲介用で、これはネットからのコピペです。なかなか見つからなかった。権利上の問題があるかもしれないので、ここに貼り付けるのは憚れるので、以下のURLを見てください。
http://blog.csdn.net/vsooda/article/details/7547431
中国語ですが、ソース表示の上にViewPlain釦があります。
CvvImageを探す以外はすごく簡単でした。今時は簡単にできるのだなと感慨に耽ってしまった。
で、カメラをスタンドにグルーで付けて、上から撮影できるようにした。
簡単だったというメモでした。
cv::VideoCapture(int カメラ番号)この番号はPCに接続しているカメラの番号なので、0から始まる。私の場合はノートPCにカメラが既に付いているので1が外付けのカメラだった。OSが認識する順なので、立ち上げ時に繋いでいると順序が入れ替わる可能性がある。結構不便。
cv::Mat これにイメージが取り込まれる。cam >> cam1image
cv::imwrite()、ファイル名の拡張子でJPGだったりPNGなどを指定できる。
CvvImageはDCとの仲介用で、これはネットからのコピペです。なかなか見つからなかった。権利上の問題があるかもしれないので、ここに貼り付けるのは憚れるので、以下のURLを見てください。
http://blog.csdn.net/vsooda/article/details/7547431
中国語ですが、ソース表示の上にViewPlain釦があります。
CvvImageを探す以外はすごく簡単でした。今時は簡単にできるのだなと感慨に耽ってしまった。
で、カメラをスタンドにグルーで付けて、上から撮影できるようにした。
簡単だったというメモでした。
void PCamClass::Run() { // Override cv::VideoCapture cam(m_nNum); cam.set(CAP_PROP_FRAME_WIDTH, 1600); cam.set(CAP_PROP_FRAME_HEIGHT, 1200); DWORD dwLastTick = ::GetTickCount(); while (1) { if ((::GetTickCount() - dwLastTick) < 334) // 3fps { Sleep(50); continue; } dwLastTick = ::GetTickCount(); cv::Mat cam1image; cam >> cam1image; if (m_bGetJPEG && !m_bGotJPEG) { /// Save to the FileName cv::imwrite(m_strFileName, cam1image); m_bGotJPEG = true; } CvvImage cimg; IplImage img = cam1image; cimg.CopyOf(&img); if (IsWindow(m_hWnd)) { HDC hDC = ::GetDC(m_hWnd); cimg.DrawToHDC(hDC, &m_rectDraw); ReleaseDC(m_hWnd, hDC); } DWORD dwRet = ::WaitForSingleObject( this->m_hTerminateEvent, 0); switch (dwRet) { case WAIT_OBJECT_0: // Prio End return; } } }
登録:
投稿 (Atom)