アフィリエイト広告を利用しています
ファン
検索
<< 2023年12月 >>
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31            
最新記事
(12/20)KI cad インストールしてみよう
(04/11)【JAVA】チョロメを外部から動作させます。 幽霊が操作してるような
(07/29)spartan3 を cy7c68013 のバルクライトで シリアルコンフィグしてみた
(07/28)ブログ村に参加してみた。いまとのころブログ村からはだれもこない^^;
(07/28)PIC16F1503 を使ってみようかな?? MPLAB 内部クロック
(07/01)からっぽのつぎ のページ きっとはげ に なんか作用するかも
(05/06)GCEでワードプレス 第2 困ったのでやり直し手順
(05/05)https://certbot.eff.org/lets-encrypt/centosrhel7-apache をみてハマったこと
(04/28)フェドラ をつかって switchbot をアクセス する。  ? 未解決
(04/02)【オープンVPN】setsebool -P openvpn_enable_homedirs 1 でうごいた
(04/01)【QT5】わからないのでタイムアウトで自動でキャンセルボタン押すメッセージボックスつくってみた
(03/31)qt5よくわからんのだが メッセージボックスの OKスイッチをタイマーで押してみた。
(03/09)【boost】message queue 使い方 目も目も
(03/08)【バカの一つ覚え】ユニークID作成とそのちょっとした応用
(03/04)【パソコン】【GPIO】いったいこれは?
(02/26)【VHDL入門】ABZ信号から Hsync Vsyncを作り出してみよう その2
(02/26)【VHDL入門】ABZ信号から Hsync Vsyncを作り出してみよう その1
(02/26)【VHDL入門】速度比較 エンコーダーABZ相 ソースファイル付き
(02/25)【VHDL入門】ロータリーエンコーダABZ 出力のサンプル 200Mhz動作?
(02/23)【VHDL入門】UART 送受信繰り返しのテストベンチ作成してみたい
最新コメント
カテゴリーアーカイブ
プロフィール
有象無象さんの画像
有象無象
はげはじめました 禿増されます。励ましのコメントお待ちしてます。  
プロフィール

広告

この広告は30日以上更新がないブログに表示されております。
新規記事の投稿を行うことで、非表示にすることが可能です。
posted by fanblog

2021年02月17日

LiveCDCustomization Linux Xfce マジこの手順で自分専用のライブCDつくれます。

# first Get Fedora-Xfce-Live-x86_64-32-1.6.iso 

wget https://dl.fedoraproject.org/pub/fedora/linux/releases/32/Spins/x86_64/iso/Fedora-Xfce-Live-x86_64-32-1.6.iso

mkdir tmp3 tmp2 tmp1

mount Fedora-Xfce-Live-x86_64-32-1.6.iso tmp3
mount tmp3/LiveOS/squashfs.img tmp2
tmp2/LiveOS/rootfs.img tmp1

cp -a tmp3 LIVECDIMG
mkdir -p squashfs/LiveOS
truncate -s $((2**33)) squashfs/LiveOS/rootfs.img
mkfs.ext4 -L Fedoralivecd squashfs/LiveOS/rootfs.img
mkdir -p rootfs
mount squashfs/LiveOS/rootfs.img rootfs

cp -a tmp1/* rootfs/

echo hostonly="no" > zzrootfs/etc/dracut.conf.d/01-liveos.conf
echo add_dracutmodules+="dmsquash-live" >> zzrootfs/etc/dracut.conf.d/01-liveos.conf
echo compress="xz" >> zzrootfs/etc/dracut.conf.d/01-liveos.conf

ln -s rootfs zzrootfs

#----------------preparation
mount -o bind /dev/ zzrootfs/dev/
mount -o bind /proc/ zzrootfs/proc/
mount -o bind /tmp/ zzrootfs/tmp/
mount -o bind /run/ zzrootfs/run/
cp /etc/resolv.conf zzrootfs/etc

#------- your -LiveCDCustomization start
chroot zzrootfs

#^^^^^^^^^^^^^^^^^^^ Customaizton braburabura some work
# for rexample
dnf update -y #brabrabra do something

#-------- your -LiveCDCustomization END

#--- Customaizton closing
exit
umount zzrootfs/dev/
umount zzrootfs/proc/
umount zzrootfs/tmp/
umount zzrootfs/run/


umount rootfs
rm -rf squashfs.img.new
mksquashfs squashfs squashfs.img.new -comp gzip
\cp -f squashfs.img.new LIVECDIMG/LiveOS/squashfs.img


###### check the Label Name
cat LIVECDIMG/isolinux/isolinux.cfg |grep CDLABEL
# you will see
#append initrd=initrd.img root=live:CDLABEL=Fedora-Xfce-Live-32-1-6 rd.live.image quiet
# append initrd=initrd.img root=live:CDLABEL=Fedora-Xfce-Live-32-1-6 rd.live.image rd.live.check quiet
# append initrd=initrd.img root=live:CDLABEL=Fedora-Xfce-Live-32-1-6 rd.live.image nomodeset quiet
# or something your CDLABEL is Fedora-Xfce-Live-32-1-6

LANG=C
mkisofs -v -r -J -l -input-charset utf-8 \
-V 'Fedora-Xfce-Live-32-1-6' \
-cache-inodes \
-b isolinux/isolinux.bin \
-c isolinux/boot.cat \
-no-emul-boot \
-boot-load-size 4 \
-boot-info-table \
-o Fedora-Xfce-Live.iso \
./LIVECDIMG

##### you will see Fedora-Xfce-Live.iso file by "ls" command
## check it using "oracle VM VirtualBox"Screenshot_2021-02-17_16-02-40.png


That is ALL ???????
This time you can Not log in by SeLinux (preventing your log in)
SELINUXが オートログインをブロックしています。 

Screenshot_2021-02-17_16-13-10.png

とりあえずっとっとっと
provisionaly using enforcing=0 kernel option
so so
Screenshot_2021-02-17_16-29-53.png

LIVECDIMG/isolinux/isolinux.cfg

default vesamenu.c32
timeout 25

display boot.msg

# Clear the screen when exiting the menu, instead of leaving the menu displayed.
# For vesamenu, this means the graphical background is still displayed without
# the menu itself for as long as the screen remains in graphics mode.
menu clear
menu background splash.png
menu title Fedora-Xfce-Live 32
menu vshift 8
menu rows 18
menu margin 8
#menu hidden
menu helpmsgrow 15
menu tabmsgrow 13

# Border Area
menu color border * #00000000 #00000000 none

# Selected item
menu color sel 0 #ffffffff #00000000 none

# Title bar
menu color title 0 #ff7ba3d0 #00000000 none

# Press [Tab] message
menu color tabmsg 0 #ff3a6496 #00000000 none

# Unselected menu item
menu color unsel 0 #84b8ffff #00000000 none

# Selected hotkey
menu color hotsel 0 #84b8ffff #00000000 none

# Unselected hotkey
menu color hotkey 0 #ffffffff #00000000 none

# Help text
menu color help 0 #ffffffff #00000000 none

# A scrollbar of some type? Not sure.
menu color scrollbar 0 #ffffffff #ff355594 none

# Timeout msg
menu color timeout 0 #ffffffff #00000000 none
menu color timeout_msg 0 #ffffffff #00000000 none

# Command prompt text
menu color cmdmark 0 #84b8ffff #00000000 none
menu color cmdline 0 #ffffffff #00000000 none

# Do not display the actual menu unless the user presses a key. All that is displayed is a timeout message.

menu tabmsg Press Tab for full configuration options on menu items.

menu separator # insert an empty line
menu separator # insert an empty line

label linux
menu label ^Start Fedora-Xfce-Live 32
menu default
kernel vmlinuz
append initrd=initrd.img root=live:CDLABEL=Fedora-Xfce-Live-32-1-6 rd.live.image enforcing=0

label check
menu label Test this ^media & start Fedora-Xfce-Live 32
kernel vmlinuz
append initrd=initrd.img root=live:CDLABEL=Fedora-Xfce-Live-32-1-6 rd.live.image rd.live.check enforcing=0

menu separator # insert an empty line

# utilities submenu
menu begin ^Troubleshooting
menu title Troubleshooting

label vesa
menu indent count 5
menu label Start Fedora-Xfce-Live 32 in ^basic graphics mode
text help
Try this option out if you're having trouble starting
Fedora-Xfce-Live 32.
endtext
kernel vmlinuz
append initrd=initrd.img root=live:CDLABEL=Fedora-Xfce-Live-32-1-6 rd.live.image nomodeset quiet

label memtest
menu label Run a ^memory test
text help
If your system is having issues, a problem with your
system's memory may be the cause. Use this utility to
see if the memory is working correctly.
endtext
kernel memtest

menu separator # insert an empty line

label local
menu label Boot from ^local drive
localboot 0xffff

menu separator # insert an empty line
menu separator # insert an empty line

label returntomain
menu label Return to ^main menu
menu exit

menu end





ちなみに この アップデートやってますが カーネルが入れ替わったことになっています
しかし 本当のカーネルは vmlinuz ですので カーネル固定です。




















l

2021年02月15日

【VHDL入門】個人で作った一番でっかいVHDLはコンパイルにえーとざっくり1時間かかるのだ

今日は VHDLの雑談 です。 画像まちがってた 直しまし   個人で作った一番 でっかいVHDL は いまコンパイルというのかな フィッターつかって 何分かかるか図ってみた。 パソコンはジーオンというCPUだ。 クロックは速くない ISEで シングルスレッドなので ひたすら時間がかかる いまコンパイル始めた 21:22分だ。  シンセシスは 大したことないな 5分ほどだ。  インプリメント 結構時間がかかる。風呂行ってこよう 風呂入ってきた  ただいまぁ  まだ おわりそうにないな  おお トランスレートは済んだらしい。  今 MAP が走ってる。  配置中らしい。  マップおわった 21:46 大体  24分 かかってる  これから 配線だ 配線は 4スレッドで動くらしい  線が通ったらしい 大体3分かな   これからがながい なにしてるんだろう 結局1時間 かかることにあいなった。  初心者が 馬鹿の一つ覚えみたいな書き方で 作ったのだが結構でっかくなったな  DDR2メモリを 自分のタイミングでリードするように シーケンサ組んだのだ。  一番めんどうなのは ピン遅延が3nぐらいあるので DDR2読み出しが 周回遅れになることです。  3nってことは 行きと帰りで 6nS 遅れるし 配線でもナノ・セカンド遅れるし  DDR2メモリが PLLみたいなのもってるんで なんとかなるみたいな話です。     万年初心者だけど アマチュアにしては 結構でかいの組むほうだと思う。 あとで 配置配線済んだ FPGAエディタの 中身 貼っておきます。  画像まちがってました こっちが一番私の履歴で おおきなVHDL使った設計です スクリーンショット_2021-02-17_22-03-06.png 配置配線.png
posted by 有象無象 at 21:10| Comment(0) | TrackBack(0) | VHDL

2021年02月14日

【VHDL入門】20分周のVHDLから シミュレーションまで

おまちかね (だれがじゃ) 単純にクロックを分周して パルスを出す回路だ。
デューティ50%と 20回に一回 1クロックパルスだす両方だ。
 あんまりデューティ50%は必要がないのだが 出してみたというだけ 芸のない回路だ。

 FPGAのなかで 50%デューティのパルスを作ってグローバルクロックに載せてるのを見たことがあるが
あれは 管理しにくいし 遅延がおきるので 扱いにくい
 元クロックとは 遅延分ずーっとずれたままになる。

 だめだとはいわないけど 私は そんなの管理できないので ・・・

また 配線が複数になるのを防ぐために 回路からは 作られたパルスを 1クロック遅らせて アウトピンにつなぐ これで アンド オア 論理がだらだら 長距離ひっぱれるのを防ぐのだ。

シミュレーションは 20分周なんて10進数なので デシマルでカウンターは表示した。

リセットしてないという苦情も 受け付けなくはないが FPGAって基本RAM動作 コンフィグ終了したところで 普通はカウンター値もゼロとなっている。 そんなデバイス特性をつかった プログラムだ
 非同期リセットもできるのだが  非同期なので リセットの瞬間 ひげがでたりするので 私はそれはきらってる。
signal R_div : std_logic:='0';  な書き方で 初期値ゼロになるの もしこれを signal R_div : std_logic:='1'
とかくとコンフィグされたとき1になるらしい。  シミュレーションのときもこれいれてないとリセットでもしないかぎり アンデファインド になるので シムできない しむしむ するには初期値がいるよってこと

20分周.png

テストベンチはこんなもの

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;


ENTITY tb_div IS
END tb_div;

ARCHITECTURE behavior OF tb_div IS

COMPONENT div
PORT(
i_clk : IN std_logic;
o_div_duty50 : out STD_LOGIC;

o_div : OUT std_logic
);
END COMPONENT;


--Inputs
signal i_clk : std_logic := '0';

--Outputs
signal o_div : std_logic;
signal o_div_duty50 : std_logic;

-- Clock period definitions
constant i_clk_period : time := 10 ns;

BEGIN

-- Instantiate the Unit Under Test (UUT)
uut: div PORT MAP (
i_clk => i_clk,
o_div_duty50 => o_div_duty50,
o_div => o_div
);

-- Clock process definitions
i_clk_process :process
begin
i_clk <= '0';
wait for i_clk_period/2;
i_clk <= '1';
wait for i_clk_period/2;
end process;


-- Stimulus process
stim_proc: process
begin
-- hold reset state for 100 ns.
wait for 100 ns;

wait for i_clk_period*10;

-- insert stimulus here

wait;
end process;

END;



ソースファイルはこんなもの 1クロック遅らせて出力してるのが 設計上負担がない

library ieee;
use ieee.std_logic_1164.all;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
library unisim;
use unisim.vcomponents.all;

entity div is
Port ( i_clk : in STD_LOGIC;
o_div_duty50 : out STD_LOGIC:='0';
o_div : out STD_LOGIC:='0'
);
end div;

architecture Behavioral of div is
signal cnt : std_logic_vector(7 downto 0) := (others => '0');
signal R_div : std_logic:='0';
signal R_div_duty50 : std_logic:='0';

begin

process (i_Clk)
begin
if rising_edge(i_Clk) then

cnt <=cnt + '1';
if(cnt=X"09")then
R_div_duty50<='0';

elsif(cnt=X"13")then
R_div_duty50<='1';
cnt<=(others => '0');
R_div<='1';
else

R_div<='0';
end if;

o_div_duty50<=R_div_duty50;
o_div<=R_div;
end if;
end process;

end Behavioral;




以上ですーーー
 おまけ むかし スパルタン3で200MHz 動作させたときの 配置配線です。
 手動で配置しないと なかなか全体として100Mhzで動作させるのは面倒です。
 ジョークなのですが 250Mhzで動くかな とやってみたところ 動きはしましたが 
 FPGAが少々熱くなるので 200Mhzに戻したときのものです。 レポートでは動かないことになっていました。
配置配線.png

 アルテラで言うと サイクロン なんかも 200Mhzぐらいで動かせればいいな 100Mhzは軽く動作するようです。
posted by 有象無象 at 09:47| Comment(0) | TrackBack(0) | VHDL

2021年02月13日

【VHDL入門】UARTを実装してみる。シミュレーターまで

https://www.nandland.com/vhdl/modules/module-uart-serial-port-rs232.html
を勝手に借りるとして
階層.png

ここに コンポーネントとして くっつけるのだ。
entityをコピーして コンポーネントにして貼り付ける。

試してみよう
 送信と受信があるので これを 1個のUART というファイルで 管理する。



library IEEE;
use IEEE.STD_LOGIC_1164.ALL;


entity UART is
generic (
g_CLKS_PER_BIT : integer := 115 -- Needs to be set correctly
);

port (
i_Clk : in std_logic;
i_TX_DV : in std_logic;
i_TX_Byte : in std_logic_vector(7 downto 0);
o_TX_Active : out std_logic;
o_TX_Serial : out std_logic;
o_TX_Done : out std_logic;

i_RX_Serial : in std_logic;
o_RX_DV : out std_logic;
o_RX_Byte : out std_logic_vector(7 downto 0)
);
end UART;
architecture Behavioral of UART is
component UART_TX
generic (
g_CLKS_PER_BIT : integer := 115 -- Needs to be set correctly
);
port (
i_Clk : in std_logic;
i_TX_DV : in std_logic;
i_TX_Byte : in std_logic_vector(7 downto 0);
o_TX_Active : out std_logic;
o_TX_Serial : out std_logic;
o_TX_Done : out std_logic
);
end component;

component UART_RX
generic (
g_CLKS_PER_BIT : integer := 115 -- Needs to be set correctly
);
port (
i_Clk : in std_logic;
i_RX_Serial : in std_logic;
o_RX_DV : out std_logic;
o_RX_Byte : out std_logic_vector(7 downto 0)
);
end component;

begin

UART_TXinst : UART_TX generic map (20)
port map (i_Clk, i_TX_DV, i_TX_Byte,o_TX_Active,o_TX_Serial,o_TX_Done);
UART_RXinst : UART_RX generic map (20)
port map (i_Clk, i_RX_Serial,o_RX_DV,o_RX_Byte);


end Behavioral;


さて それぞれの TX RXは 単純に元々のものをコピーしてきただけなので 階層としては
階層拡大」.png

 ここまでいいでしょうか  絵柄はさらに上にシミュ用の あれがなにしてます。
 シミュレーター用は VHDL TB テストベンチの略でしょうけどこれでつくります。

作ったテストベンチは こんな感じ 
  16進数で 送信に突っ込んで スタートして 送信されたデータを クロックで遅らせて
 受信に返します。 この結果がデコードできればいいわけです。

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;


entity UART is
generic (
g_CLKS_PER_BIT : integer := 115 -- Needs to be set correctly
);

port (
i_Clk : in std_logic;
i_TX_DV : in std_logic;
i_TX_Byte : in std_logic_vector(7 downto 0);
o_TX_Active : out std_logic;
o_TX_Serial : out std_logic;
o_TX_Done : out std_logic;

i_RX_Serial : in std_logic;
o_RX_DV : out std_logic;
o_RX_Byte : out std_logic_vector(7 downto 0)
);
end UART;
architecture Behavioral of UART is
component UART_TX
generic (
g_CLKS_PER_BIT : integer := 115 -- Needs to be set correctly
);
port (
i_Clk : in std_logic;
i_TX_DV : in std_logic;
i_TX_Byte : in std_logic_vector(7 downto 0);
o_TX_Active : out std_logic;
o_TX_Serial : out std_logic;
o_TX_Done : out std_logic
);
end component;

component UART_RX
generic (
g_CLKS_PER_BIT : integer := 115 -- Needs to be set correctly
);
port (
i_Clk : in std_logic;
i_RX_Serial : in std_logic;
o_RX_DV : out std_logic;
o_RX_Byte : out std_logic_vector(7 downto 0)
);
end component;

begin

UART_TXinst : UART_TX generic map (20)
port map (i_Clk, i_TX_DV, i_TX_Byte,o_TX_Active,o_TX_Serial,o_TX_Done);
UART_RXinst : UART_RX generic map (20)
port map (i_Clk, i_RX_Serial,o_RX_DV,o_RX_Byte);


end Behavioral;


特に怪説いらないと 思いますが
 プロセスという形式で  クロックをつくって
 クロックのエッジで 送信からでた シリアル信号を 1クロック遅らせて 受信にいれます。
 
今回 
UART_TXinst : UART_TX generic map (20)
port map (i_Clk, i_TX_DV, i_TX_Byte,o_TX_Active,o_TX_Serial,o_TX_Done);
UART_RXinst : UART_RX generic map (20)
port map (i_Clk, i_RX_Serial,o_RX_DV,o_RX_Byte);

 非同期のクロックを20クロックでという ことにしたので
 たとえば クロックが20MHzなら 1Mビット が一秒に転送されます。

では ここでシミュレーターを起動してみましょう。
 TBとしてさっきのファイルが追加されているので シミュレーターがクリックすれば起動します。
シミュレーター起動前修正版.png

この絵のなかの SimulateBehavioralModel というところをクリックすると なんとまぁ
 ということです TBをえらんで居る状態です ここで クリックすると

シミュレーター起動.png

さあ これで  VHDLを書いた  テストベンチを書いた シミュレーター起動した
という一連の流れの説明を終了します。
お疲れ様でした。

 ちなみに私は アルテラ 派です なんで ザイリンクスISEやねん という話ですが
 実はー  VHDLシミュレーターの起動は こっちが 速いのです。
 楽 だから プリミティブが アルテラ出ない場合は こっちで ちゃっちゃと シミュレーターです。



posted by 有象無象 at 12:16| Comment(0) | TrackBack(0) | VHDL

【VHDL入門】最初の扉を叩くのだ。

昨日 Xilinx_ISE_DS_14.7_1015_1 をコピーして ダウンロード 早速洗礼をうけた
[liveuser@localhost Xilinx_ISE_DS_14.7_1015_1]$ ls
Microsoft.VC90.CRT autorun.inf common edk ise lib planahead sysgen xinfo xsetup
Microsoft.VC90.MFC bin data idata labtools msg planahead_wp webpack xinfo.exe xsetup.exe
[liveuser@localhost Xilinx_ISE_DS_14.7_1015_1]$ ./xsetup
/home/liveuser/Downloads/Xilinx_ISE_DS_14.7_1015_1/bin/lin64/_xsetup: error while loading shared libraries: libncurses.so.5: cannot open shared object file: No such file or directory
[liveuser@localhost Xilinx_ISE_DS_14.7_1015_1]$

あーあ ライブラリがリンクがないらしい まぁいいだろう /usr/lib64 ここの ncurses のライブラリを あれしてなにだ 具体的には ln -s /usr/lib64 を 我がコンピュータは 64ビット版なのでこうだ。

$ ls -1 /usr/lib64/libncurses*
/usr/lib/libncurses.so
/usr/lib/libncurses++.so
/usr/lib/libncurses++w.so
/usr/lib/libncursesw.so
/usr/lib/libncurses++w.so.6
/usr/lib/libncursesw.so.6
/usr/lib/libncurses++w.so.6.0
/usr/lib/libncursesw.so.6.0

$ sudo ln -s /usr/lib64/libncursesw.so.6.0 /usr/lib64/libncurses.so.5
$ sudo ln -s /usr/lib64/libncursesw.so.6.0 /usr/lib64/libtinfo.so.5


まぁ いいだろう それにしても でかいファイルだ  /opt にインストールしたいので root でインストールする。
xilinxinstall.png

 インストールの間暇なので  スペースコブラでもみながらまつ 左腕に銃を持つ男だってさ
スターウォーズみたいな 宇宙人がでてくる。 ブサイクな おっさんヒーロー? だ。
地球人にしては あれでなにな 女性たちも登場する。 

 ちょっとおしゃべりだ インストールすむまでの・・
具体的なことが重要なので 具体的に 動作済みのソースを WEB上から いただいて それをもとに解説してみる。 やりたいことは すでに動いているIPを 自分のVHDLにつないで動かす シミュレーターをつかう。 この順番 だれのためって 忘れっぽい 自分のためだ。 ははは
 数回の 連載?なのだが ほぼこれで フィッターで一時間級の 規模なら 個人でもできるようになるエッセンスは入っているつもりだ。
あと 老婆心なのだが ある寺 アルテラ VS ザイリンクス でいうと
アルテラは 配置のマニュアルは有償品の開発ツールでないとできないが ザイリンクスなら WEBパック無償でできる。 これは経験則だが 20MHzを超える設計は 何らかの配置配線が必要なことが多い
 私の経験では FPGAを250Mhzで動作させたとき これを 完全にコンパイラ任せにすると 全く動作しなかった ^^; マニュアルで フロアプランすると 普通に動作した。
 アルテラでもやってみようとおもうのだけど  普段の仕事が ご多分にもれず バスの切り替えとか
そんなものが大半だから アルテラでのフリーで事足りる。
  私のアルテラ歴では   動作も5MHz とか10Mhz ぐらいでしか組んだことがない ^^; 20Mhz超えた設計なんてしたことがない。^^; クロックついてりゃいいみたいな。
  私のザイリンクス歴では 200Mhz超えたものばかり 20Mhzでは許してもらえない^^;ときは フロアプラン無料のザイリンクス一択だ。 

ちょっとVHDLやろうとおもったので ザイリンクスダウンロードしてみよう 
【VHDL入門】UARTを実装してみる。シミュレーターまで
【VHDL入門】20分周のVHDLから シミュレーションまで
 分周はいくらかやり方があって カウンター地との比較をしてみた。 本当にカウンターの上位ビットをそのまま出力するのもありだ。 1,2,4,8・・・分周になる。
余談編
【VHDL入門】個人で作った一番でっかいVHDLはコンパイルにえーとざっくり1時間かかるのだ
 これは アマチュアレベルではでっかいほうだ、そして250Mhzで動作しているので おきらくとは言い難い。 小さなVHLDソースでは 簡単に250Mhz動作するが 大きくなると うざい。
 ちいさなVHLDソースを でっかい FPGAに コンパイラまかせフィットさせると 本当にスピードでませんぜだんな 10Mhz とか 5Mhz とかしか動かん ^^; なんじゃそりゃみたいな
 DDR2つかったのだけど あれ面倒くさかった  。

インストールが済んだ  
cd opt/Xilinx にはいって  セットアップを起動する
  /opt/Xilinx/14.7/ISE_DS/ISE/bin/lin64 ここに起動ファイルがあるのでここの iseを起動する。
ありゃ ライセンスが いるらしい。

ライセンス.png

ライセンスファイルが手に入ったので
export XILINXD_LICENSE_FILE=/home/liveuser/.xilinx/
/opt/Xilinx/14.7/ISE_DS/settings64.sh
みたいな 環境変数に ライセンスファイルの置き場を指定 そうすると
 起動できます。

これで コンソールから ise エンターで 起動できます。 

早速起動して uart を いれみます。 
https://www.nandland.com/vhdl/modules/module-uart-serial-port-rs232.html 
のファイルを あれします。

file ー> newproject  でnewproject.png

プロジェクト名を 例えば myuart とかいれます。 ここで どのデバイス使うかとか設定ありますが
とりあえず spartan6 ぐらいいれましょうか 一通りいろいろついてますので
 モデルシムつかえるのかな? ちょっとわかっていません。追って考えましょう
デバイス選択.png

ファイル追加して VHDLモジュールを つくります。 最初てきとうに

https://www.nandland.com/vhdl/modules/module-uart-serial-port-rs232.html 
にあるように 同じ名前でファイルをつくります。 送受信の箱をつくって
そのしたに階層構造で このページのデモをつくってみます。

  コンポーネントという形で 下層においていきます。
 entiry なんちゃら is
なのですが
 componet に is はつきません  これ面倒です。

最上位まだ書いていませんが コンポーネントをこんな感じにおいていきます。

entity uart is


end uart;

architecture RTL of UART_TX is
component UART_TX
generic (
g_CLKS_PER_BIT : integer := 115 -- Needs to be set correctly
);
port (
i_Clk : in std_logic;
i_TX_DV : in std_logic;
i_TX_Byte : in std_logic_vector(7 downto 0);
o_TX_Active : out std_logic;
o_TX_Serial : out std_logic;
o_TX_Done : out std_logic
);
end component ;

component UART_RX
generic (
g_CLKS_PER_BIT : integer := 115 -- Needs to be set correctly
);
port (
i_Clk : in std_logic;
i_RX_Serial : in std_logic;
o_RX_DV : out std_logic;
o_RX_Byte : out std_logic_vector(7 downto 0)
);
end component ;
begin


end Behavioral;










posted by 有象無象 at 05:45| Comment(0) | TrackBack(0) | VHDL

2021年02月12日

ちょっとVHDLやろうとおもったので ザイリンクスダウンロードしてみよう

web packが無料ということで いってみた なんと 7GB超えだ。 ダウンロードしかけて寝るしかない UART がほしいなぁと思ったら  おちてた https://www.nandland.com/vhdl/modules/module-uart-serial-port-rs232.html  何も考えず これつかおっと   例えば20MHZ のシステムクロックで 1MHZの シリアル通信するなら  g_CLKS_PER_BIT : integer := 20 とすればいいらしい  へぇ へぇ へぇ
posted by 有象無象 at 22:45| Comment(0) | TrackBack(0) | VHDL

2021年02月09日

QT5 widget をNEWしたとき this をいれると 親になるのかな 

QT5 widget をNEWしたとき this をいれると 親になるのかな   よくわからんんが いくつか試したところ this 入れると 親になるらしく 自分がけされると けされる 見たいなんだけど よくわからん。

ノイズなのか相対性理論なのか

まぁ そいうことです。 信号の反射とか 特性インピーダンスとか これって光速より速くは 電線の向こうの世界が見えないということです。



ノイズ対策は いろいろ駆り出された経験があります。
 一番えぐかったのは 某太陽電池製造工場 でのできごと ノイズなのかなんだかしらんが 
プラズマ作成装置 5KW 7KW 8KW のチャンバーで マッチングが外れ ボン ドカン そうなったら お掃除に200万円掛かる

 という事件  これも簡単になおったな はっはっは
 治具屋としては ボンしてくれたほうが うれしい
 直し方は簡単 絶縁だ フェライトコア だ バランスだ
こんな簡単なことが なぜできない 
 アースとか グランドループとか どうでもいいことばかりいわれてて
まぁいいだろう 誤解は 商売とつながる 
殆どの 現場で技術者とは 意見が一致しない はっはっじゃ


プリント基板 に関して
 プリント基板は大雑把に 60Mhzを越えてくると あれですよ。 だんだん 光の速度の限界が影響として見えてきます。 だって 1ナノ秒で 20cmぐらいかな 桁間違ってないかな
 秒速30万キロメートルの電気信号というけど プリント基板上では20万キロ/s 10何乗だっけ  よりちょっと速いぐらいです。 TTLの立ち上がり時間で 200cmぐらいすすみます。 高速のICだったら 立ち上がり時間で10cmとか そんなもんです。 ナノ秒でみると プリント基板の電線の長さは 光速の移動速度をもってしても  往来の 足跡が 見えてきます。  つまりは 光の速度がどうのこうの の領域に入ります。
 とにかく 日常の足し算引き算だけではなく 反射や電界の乱れなど  いろんな積分要素がみてきます。
つまりは 日常感覚からは はずれてきます いや だれにとっての日常かというと 普段台所で 大根をきる日常からすると ずいぶんずれてくるということです。

 50mhzいうと 周期が 20ナノかな あってるかな  オンオフする時間で  基板内を 信号の反射が何往復かしますね。  信号線の長さが10cmとすると 20回ぐらい 反射波が往復してるかな
 とにかく 反射波 の数を 指でかぞえるぐらいの領域に入ります。
 減衰させないと 次の信号に かぶる みたいな    だから 信号の減衰が問題視されます。

 リンギング とか あれとか なにとか 見えてくるわけです。

 
じつは 相対性理論がノイズ対策の世界には 顔をだします。
 相対性理論があってるとか まちがってるなんてどうでもいい話です。
 とりあえず 高速度に近い速さで 電気は動作します。 当然その世界です。

これを 日常感覚で ノイズ対策しようとする エンジニアが多すぎです。 学校で習ったことわすれたのかい? という話です。
 びっくりさせられるのは Cを 電線につっこんでノイズ対策 なんて びっくりです。ほんとびっくり
 ノイズ対策といういみでは C も Lも 同じものです  位相が逆なだけです。
 抵抗にたして どちらも 90度ずれる それが プラスか マイナスかなだけです。
そんなもの 電線にいれるなよな と ぷんぷんです。 積分回路つくるとノイズ止まる?! それって まァいいだろう 


 そんな感じです。




2021年01月29日

opencv c++ Qt5 始めます。今日は パターンマッチングの 

みなさんこんばんは
 今日から オープンCVを使うことにします。

 パイソンなどはわかりません 読めませんし書けません C++ならなんとかかんとかわかります 。

 想定するシステム
 OS フェドラ ライブCD モディファイ
 開発環境 OPENCV C++ boost libarary
 動作チェック環境 QT5

 なぜそうしたか QT5は WINDOWSでも LINUXでも動作します。
 C++は WINDOWSでも C++でも 動作します。

組み込みでは見えないので 見える形に Qt5で 表示します。
  OPENCV と QT5の 非互換部分は MATが BGR でRGBでないというだけです。

 MATと QIMAGEは 簡単に 変更できます。 そんなこんなです。

 今後の予定 
  フェドラのライブCDを 改めて モディファイします。
  今日の予定

 今日はつれづれなるままに パタンマッチングを OPENCV GPUで行います。
 だれかのお役に立つかしら?

  OPENCVは ここ
でコンパイルしたものを使う

オープンCVのフォーマット をQImageに変換するには

まず RGBへ変更してから
cv::Mat BGR2RGB(cv::Mat m_src)
{ cv::Mat srcRGB;
cv::cvtColor(m_src, srcRGB, cv::COLOR_BGR2RGB);
return srcRGB;
}
QImage tmpimg = QImage(matRGB.data, matRGB.cols, matRGB.rows, static_cast(matRGB.step), QImage::Format_RGB888);


これで QImageに変換できる。
 接点は ここだ 
GPUつかうと 戻り値に CV_32Fがときおりある。これが鬼門で

double minVal,maxVal;Point minLoc,maxLoc;
minMaxLoc( resoltclone, &minVal, &maxVal, &minLoc, &maxLoc );
(resoltclone).convertTo(dst,CV_8U,255.0/(maxVal-minVal),-minVal);
cv::cvtColor( dst.clone(), img_Result, CV_GRAY2BGR );

こんな感じで GBRに変更すると QTに簡単に表示できる。
 今日のところは CV Mat での BGRを QImageに変更する。
しばらくは RGB の値が同じ3チャネルをQImageの モノクローム扱いで逃げ切る。


 いよいよGPUを使ったパタンマッチングだ。

ところで QTを使わないことを想定して
 便利な QUEUE 作ってみた  このキューで スレッド間の 連絡ができる。

#ifndef LOCKEDQUEUE_H
#define LOCKEDQUEUE_H
#include <atomic>
#include <queue>
#include <mutex>
#include <boost/filesystem/convenience.hpp>
#include <boost/interprocess/sync/interprocess_semaphore.hpp>
#include <thread>
template<class X>
class LockedQueue
{
public:

LockedQueue()
{
sem = new boost::interprocess::interprocess_semaphore(0);
flg_flush = false;
end = false;
}
virtual ~LockedQueue()
{

end = true;
sem->post();
sem->post();
sem->post();

}
void quit()
{
m.lock();
end = true;
sem->post();
m.unlock();
}

void enqueue(X x)
{
m.lock();
data.push(x);
sem->post();
m.unlock();
}

int dequeue(X * ret)
{
int retv=0;
sem->wait();
m.lock();
if (end)
{
end = false;
m.unlock();
return -1;
}
*ret = data.front();
data.pop();
m.unlock();


if (ret == nullptr)
{
return -1;
}

if (end) return -1;
return retv;
}

std::atomic_char16_t end;
std::mutex m;
std::queue data;
boost::interprocess::interprocess_semaphore *sem;
std::string eod;
std::string *ret;
std::atomic_bool flg_flush;
};

#endif // LOCKEDQUEUE_H


これで シグナル飛ばさなくても 繋がります。
テストは


lq= new LockedQueue();

std::thread *a=new std::thread([this]()
{
lq->enqueue( "aaa");
lq->enqueue( "heo");
lq->enqueue( "ddd");
lq->enqueue( "aaa");
lq->enqueue( "aaddda");
}
);
std::thread *b=new std::thread([this]()
{
while(true){

std::string str;
if(lq->dequeue(&str)==-1){break;}
std::cout << str<join();
a->join();


動作テストは 

aaa
heo
ddd
aaa
aaddda


クラスはテンプレート 使ってるので このキューは ポインタでも遅れます。

 スレッド間を このパイプで ポインタでもなんでも 送れるし ウェイトないので テキパキ動作します。

 コテコテの使い方としては  new したクラス (インスタンスを キューにいれて おくります
 それぞれ別スレッドでうごかせば キューのなかで 動作しならが 受け取りがのキューに いきます
ここで デリートするなんて 使い方もできるかもしれません。








2021年01月24日

ソートしてから 一番小さい 番号を みつける スレッドID スレッド番号を取得表示 C++

std::showbase<#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <boost/foreach.hpp>
#include <random>
std::random_device rnd; // 乱数生成器(非決定的)
std::random_device rnd; // 乱数生成器(非決定的)
class Myclass ///// 馬鹿の一つ覚えなのでストラクトもクラスで書く
{public:
std::string Nanja;
std::string Kanja;
uchar hogera;////////////////ここにある数値で ソートする。
};

typedef std::map container;
typedef std::pair value_type;


struct second_order {
bool operator()(const value_type& x, const value_type& y) const {
return x.second.hogera> y.second.hogera;
}
};

int main() {
container src;
for(int i=0;i<26;i++)
{char arr[] = "";
arr[0]=0x41+i;
std::string str(arr, sizeof(arr) / sizeof(arr[0]));
uchar a = rnd();//どでかい数字が帰ってくるので0から255までに抑え込む
Myclass tmpmyclass;tmpmyclass.Kanja="kanja";tmpmyclass.Nanja="nanja";tmpmyclass.hogera=a;///////////クラスをつかうだけなので 適当に固定値で 数値だけ乱数
src.insert(std::make_pair(str,tmpmyclass));
}
Myclass tmpmyclass;
tmpmyclass.hogera=0;
src["A"]=tmpmyclass; src["あ"] = tmpmyclass; tmpmyclass.hogera=2;; src["い"] = tmpmyclass; tmpmyclass.hogera=rnd(); src["天涯孤独"] = tmpmyclass; tmpmyclass.hogera=rnd(); src["損"] = tmpmyclass;


std::priority_queue, second_order> que;
std::pair p;
BOOST_FOREACH(p, src) { que.push(p); }
std::cout <
posted by 有象無象 at 08:41| Comment(0) | TrackBack(0) | C++

2021年01月14日

同軸ケーブルはノイズ弱いから使わぬことだ。

ノイズに弱い から 使わぬことだ
ホンマデッカ と言われそうだが 
ノイズで困った現場で 信号線を同軸ケーブルに置き換えて
ノイズが止まった事はないからね ハート(トランプ)

同軸ケーブルケーブルが ノイズに強い理由などないです。
 同軸ケーブルのノイズ耐性が高いなどという記事が
  数式つけて 学者みたいな説明サイトがいくつもあるが
  なんの根拠もない。 
 相互インダクタンスを引き合いに外乱を受けないみたいな論理展開をしているものまであった、 
 ひどいものだ もしそれが 本当なら 同軸ケーブルをつかっているアマチュア無線家が
 困るわけはない 意外と アマチュア無線家がうけているノイズは近場のノイズなのだ。

網線を シールドと読んだり 。。呼んだり 電気はプラスマイナスで一体だ。
 信号線を網線がシールドしている という言い方は マイナス側がむき出しという話です。
 プラスマイナスのマイナスが特別な存在のような言い方だが プラスマイナスで一体だ
 ひどいなぁ 

相互インダクタンスを引き合いにして ノイズに強い証明 と書かれていた 
これも 嘘だ 同軸ケーブルの芯と網線の 相互インダクタンスなど あってないような
冗談かと思ったが ハート(トランプ)

とにかく 同軸ケーブルでは ノイズ対策にはならないと 断言しておく

説明欲しい人 ??? 手をあげて 
  本質的な原因は 網線と芯線の形が違うから です。 これを不平衡といいます。
  電磁気学のしょほの初歩をならえばわかりますが  形状が違うということは電気力線の形が非対称です。
  反射という話がありますが  同軸ケーブルは 編み線がわと 芯線の 反射が異なります。
  これって 凄まじい話です。 
   例えば  一本の抵抗器で 特性インピーダンスに合致した抵抗器で単純終端すると
  アンバランスを起こして 網線側と 芯線で 反射がことなります。  なんだかわからなくなります。

  同軸ケーブル用の終端抵抗器が売られていますが これは きれいに全体的に抵抗器が貼られています。
  ひどい 終端は チップ抵抗が 内部にはられていて これは アンバランス起こします。

  そんなむずかしい終端抵抗器をかわなくても 平行線なら簡単です。 

 検証できます  アマチュア無線機に同軸ケーブルをつないで ノイズ多いなぁ とおもったら
 同軸ケーブルを4ターンほど フェライトコア通してみてくだされ。 ノイズへります。

  つまり とある作業をするとノイズが減る という 事実は もともと ノイズに弱いということです

  同軸ケーブルがノイズに強いという話は  そもそもが デタラメ ということです
 洗脳ですので  きをつけましょう

  同軸ケーブルがノイズに強い その証明みたいなサイトは 上からしたまで 嘘です。

 また細かなことをいうと  
 無限長にして テスターで 抵抗を測ると50Ωとか 特性インピーダンスになるというのもこれも嘘です。 これも周波数の関数で 直流で測ると 複雑な波形になります。 測ろうと当てた瞬間と (インパルス) と 安定状態では  抵抗値ことなります。   なんといいていいやら

水マッチ.png

 こんな話です。  それが真実です。  えっ 教科書とちがうって?
 教科書が 間違ってるのではなく 回答は こう書くべきと いう模範解答が 間違ってるのですからしかたありません。

 立場によって 答えは異なるが 電気の振る舞いは変わらない
 私が 教師なら マッチングはこれで OK 入力波形に依存しないと 答えます

 しかし エンジニアとして 現場にでると これは嘘だと いいます。
 あたりまえですね  。 電気の振る舞いは 教科書通りなのですから

 矛盾してるって ???  電気の振る舞いはマックスウェルの電磁方程式 の通りで
  この方程式は 日常生活範囲では 絶対不変 です。  違う宇宙ならちがうかもしれませんし
  宇宙のどこかでは 崩れるかもしれませんが 地球上では まず狂うことはありません

  解説します。

  工学的には  特性インピーダンスで終端すると OK と言わざるをえません
  しかし 電磁気学的には 形状影響します。


   回路図としては 50オームの 特性インピーダンスの線材を 50オームで終端しているので OKです  異論はないでしょう

   しかし 同軸ケーブルの形状に いきなり 抵抗器で終端 絵のように終端すると 電界 磁界は きれいに終端されません。  芯線と 網線では 反射率がことなります
   これは 2Mヘルツみたいな 低い周波数から発生します。 こまかなことをいうと 100KHZぐらいから 見えてきます。
   50Mhzみたいな周波数では 確実に変なことになります。


 どんな波形でも?  実際 特性インピーダンスは周波数の関数です。 
   数ヘルツみたいな低い周波数と 100khZでは 大きくことなります。 100KHZからメガヘルツレベルでは 似たようなことになります。 また GHZになってくると 伝送モードが変わってきますのでまた振る舞いはことなります。
  
  そして 計算しませんが  被覆と芯線の 相互インダクタンスなんて たかがしれています。

 これを 大きくするには トランス結合みたいな話で フェライトコアを数ターンさせると 結合が桁違いに大きくなります。 つまり 同軸ケーブルは フェライトコアをとおさねば すぐに 被覆と 芯線がアンバランスをおこし  ノイズまみれになります

  信じないのは 勝手ですが  信じようがしんじまいが 事実は事実です。
 脳が固着起こした 上司にさからっても無駄です。  ノイズ対策は しれっと エンジニアが 現場でおこない アース強化しましたぁ  なおりましたぁ  と しれっと 報告しておくのが一番です。

 

 本当のことをいうと 10人中10人  アースがノイズ対策と答えます
  100人ぐらいあつめても  だいたい 似たような答えです
 ところが 1000人ぐらい エンジニアをあつめると ・・・・
  
  人類をみるには 確率で 会話をするのがそさそうです
 

 こんな意見のひとが ナン % 。。。。。; はっはっは

  

































  



































2021年01月12日

カメラがつながってるポートをトラステッドに変更してみたら いい感じ さすが無法地帯

ifconfig してみると

eno1: flags=4163 mtu 1500
inet 192.168.0.10 netmask 255.255.255.0 broadcast 192.168.0.255
            |

eno2: flags=4099 mtu 1500
ether 90:b1:1c:0d:3b:6c txqueuelen 1000 (Ethernet)
            |
np1s0f3: flags=4163 mtu 1500
inet 169.254.0.100 netmask 255.255.255.0 broadcast 169.254.0.255
でてきた これが イーサーネットのカメラにつながってる

firewall-cmd --list-all-zones
  ここで trusted (active) がでてくる これに先の あれをなにする。
trusted (active)
target: ACCEPT
icmp-block-inversion: no
interfaces: enp1s0f3
sources:
services:
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:

firewall-cmd --zone=trusted --change-interface=enp1s0f3 --permanent
firewall-cmd --reload

これで 無造作につながらるはず



Qt5 モノクロームをR,G,Bでそれぞれ表示する 高速^^;QTだからこそ?の裏技

前提 条件 RGBの cv:: Mat 形式が入力されたとする。
 これはうまくいった 話だ 読み進めるとあ〜だめだった みたいなことは ない 多分^^;
freevideo-2021-01-13-005936.gif

Matを 3チャネルでコピーして RGB をそれぞれ 表示すると時間がかかる
色別に 0をR 1をG 2をB 3をカラーとして
case 0:
planes[1]=Mat::zeros(matRGB.rows, matRGB.cols, CV_8UC1);//G
planes[2]=Mat::zeros(matRGB.rows, matRGB.cols, CV_8UC1);//B
merge(planes,matRGB);
break;

こんなことをすると 時間がかかるので 
cv::Mat matAlpha;
cv::Mat matRGB=matRGBinput.clone();

std::vector planes;
planes.clear();
cv::split(matRGB, planes);
switch(this->m_alpha)
{
case 0: matAlpha=planes[0];break;
case 1: matAlpha=planes[1];break;
case 2: matAlpha=planes[2];break;
}cv::bitwise_not(matAlpha, matAlpha);
で済ませる
     早い話がモノクロームで RGBそれぞれとる。
そもそもがMatは BGRの並びだが ここではRGBで入ってくるようにした。
 ちなみにBGR とRGBの入れ替えは
    cv::split(matRGB, planes);
 して 別のstd::vector planes2nd;
     planes2nd.pushback(planes[2]);
   planes2nd.pushback(planes[1]);
   planes2nd.pushback(planes[0]);
merge(planes2nd,matRGB);
だったかな 確認オネ 順番が違う。入れ替えればいい

if(this->m_alpha!=3){
QImage _Alpha = QImage(matAlpha.data, matAlpha.cols, matAlpha.rows, static_cast(matAlpha.step), QImage::Format_Alpha8);
QAlpha =_Alpha.copy();
}else
{
QImage tmpimg = QImage(matRGB.data, matRGB.cols, matRGB.rows, static_cast(matRGB.step), QImage::Format_RGB888);
tmpimg1 =tmpimg.copy();
}

 な感じで QTのアルファ にコピーする。
そして 背景色を  次のような感じで変更しておく
すると 背景色が 見えるので RGB の表示で 青はよくみえないので シアンで代替して表示させた。

switch (alpha) {
case 0:
m_QAlphaimageWidget->setStyleSheet("background-color:red");break;
case 1:
m_QAlphaimageWidget->setStyleSheet("background-color:green");break;
case 2:
m_QAlphaimageWidget->setStyleSheet("background-color:cyan");break;

break;
}





 これをQt5で 表示する。 表示用のウィジェット は こんなやつだとする。
 こいつは setImg( QImage &img ) されるとすぐに 表示をアップデートする。 やつだ
 
ImageWidget::ImageWidget(QWidget *parent ):QGraphicsView(parent)
{
}
ImageWidget::~ImageWidget()
{

}

void ImageWidget::paintEvent( QPaintEvent *event )
{ Q_UNUSED(event);
QPainter widgetpainter( viewport() );
// widgetpainter.setWorldTransform( m_matrix );

QImage qimg = m_img.scaled(
viewport()->width(),
viewport()->height(),
Qt::KeepAspectRatio,Qt::FastTransformation);
widgetpainter.drawImage( 0, 0, qimg );
}


void ImageWidget::setImg( QImage &img )
{
m_img = QImage( img );
viewport()->update();
}


まぁいいだろう。

blue2blue.png
blue2cyan.png


2021年01月11日

baumerカメラをQT5で表示してみた。

baumer って スイス製なのかな たぶん  サンプルを OPENCVで カラー読み出しして それをQTの QIMGにして   リアルタイムに表示してみた。   いい感じだ。  サンプルのプログラムが c++ で つくられていたのだが バッファーなどが クラス化されていない コールバックがバリバリのタイプのサンプルだ。 コールバックを バインドして Cに見せかける そうすると クラスのメンバーでも まるでスタティックのように扱える。  原理としては インスタンス化されたときのアドレスを取り出すなんていうのだが  C++は 引数の型で あれこれできるので マングリング という仕組みがあるそうだ。  これを 紐解いて Cのfunctionに見えるようにすると  いい  サンプルのプログラムの コールバックを これで 紐解き クラス化する。  baumer のサンプルではBGAPI2::ImageProcessor で ネットをスキャンしたりして  同社の製品を探し出しリスト化する。   だから このあたりは スタティックでもいいのだが ・・  結果 まだ集計表示がまだだが 画像だけは RGB それを R G B に分解して表示してみた。 カラーリアルタイム分離.png QT5 での表示 カメラの情報を QWIDGETで表示するよてい 作りかけがうつってる。    こんな風にしたい イーサーネットポートの数 と IPアドレス  たとえば 4ポートイーサーネットもってると これを表示  カメラを検出 露光時間などの表を 表示  変更は一括で   リアルタイムで マーカーを 検出する みたいな。 はっはっは

2021年01月07日

QT5 QMessageBox auto close in X seconds

意外とおちてない これは メッセージボックス閉じてから メインウィンドウも閉じるみたいな

{
QMessageBox mbox ;
mbox.setWindowTitle(QString("attention"));
QString msg ="--------------------------------\n";
msg+="おわこんです \n";
msg+=" exit!! \n";
msg+="********************************\n";
mbox.setText(msg);
mbox.show();
mbox.setStandardButtons(QMessageBox::Ok);
QTimer::singleShot(700, &mbox, SLOT(close()));
mbox.exec();
QTimer::singleShot(700, this, &MainWindow::close);

}

QT5 超初心者向け QT5スケルトン

スケルトンです 起動したときに 前回動作したときの 配置サイズを戻します。
connect(this,SIGNAL(objectNameChanged(const QString &)),this,SLOT(OnobjectNameChanged(const QString &) ));
this->setObjectName("きょうも能天気♪");
はあまり意味ないのですが メインウィンドウでなけば あとから 名前変更になります。
そのとき のタイミングでうごけます。 メインウィンドウは 最初から名前一定です。
 形が同じなのでいれておきました。 ちゃんちゃん
 


Qt5main_hborn.png
Qt5main_cppborn.png
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
Q_OBJECT

public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
public slots:
void OnobjectNameChanged(const QString &objname);

protected:
void closeEvent(QCloseEvent *event) override;
void readSettings4restoreGeometry();

private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "QSettings"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(this,SIGNAL(objectNameChanged(const QString &)),this,SLOT(OnobjectNameChanged(const QString &) ));
this->setObjectName("きょうも能天気♪");
}

MainWindow::~MainWindow()
{
delete ui;
}

void MainWindow::OnobjectNameChanged(const QString &objname)
{Q_UNUSED(objname);
QSettings setting("setting.ini", QSettings::IniFormat);
restoreGeometry(setting.value("geometry").toByteArray());
restoreState(setting.value("windowState").toByteArray());
}
void MainWindow:: closeEvent(QCloseEvent *event)
{Q_UNUSED(event);
QSettings setting("setting.ini", QSettings::IniFormat);
setting.setValue("geometry", saveGeometry());
setting.setValue("windowState", saveState());

}


2021年01月05日

linux QTで パソコンで カメラを取得し 写すというところから OPENCVを使いますいつも 工事中

万年初心者の 海蘊です。
だいたい 前にすすまないひとです。 いつものように原理から メモ取りながら 
そして なにかするには馬鹿の一つ覚えですすめます。
 例えば 配置はあれですよ グリッドばっか とか  リソースから画像を読むときは この方法だけとか
作業限定で やります。 むずいテクニックは使いません。

カメラを取り込む前に まずファイルを読んでうごかします。

 

馬鹿の一つ覚え1 リソースから cv::Mat に 画像をいれる

cv::Mat loadFromQtResouce(QString qrc, int flag = cv::IMREAD_COLOR)
{QFile file(qrc);cv::Mat m;
if(file.open(QIODevice::ReadOnly))
{qint64 sz = file.size();std::vector buf(sz);
file.read((char*)buf.data(), sz);
m = cv::imdecode(buf, flag);
}else
{qDebug() << "OpenCV loading time: " ;}
return m;
}

馬鹿の一つ覚え2 画像は UIのフレームの中にいれるということしかしない

馬鹿の一つ覚え3 フレームには グリッドレイアウトしかいれない

つぎのクラスは  GUIで メインUIに置いた フレーム に グリッドレイアウトをおいて 画像を置く
クラスです。

class LoadImg2UIFrameWithSetting_QGridLayoutToFrame
{
public:
LoadImg2UIFrameWithSetting_QGridLayoutToFrame(QFrame *frame ,QWidget *parent=nullptr):parent(parent)
{
m_frame=frame;
m_gridLayout = new QGridLayout(frame);
m_tmpimageWidget=new ImageWidget(parent);
m_gridLayout->addWidget(m_tmpimageWidget);
}
~LoadImg2UIFrameWithSetting_QGridLayoutToFrame()
{
delete m_gridLayout;
delete m_tmpimageWidget;
}
ImageWidget *m_tmpimageWidget;
void setSrc(cv::Mat *src)
{
this->m_src=src;
}
cv::Mat BGR2RGB(cv::Mat m_src)
{
cv::Mat srcRGB;
cv::cvtColor(m_src, srcRGB, cv::COLOR_BGR2RGB);
return srcRGB;
}
cv::Mat *m_src;

void setCanny(cv::Mat matRGBinput )
{
cv::Mat mono,canny_img,m_dst;
cv::cvtColor(matRGBinput, mono, cv::COLOR_BGR2GRAY);
Canny(mono, canny_img, global_param[4], global_param[5],3);
cv::cvtColor(canny_img, m_dst, CV_RGBA2RGB);
QImage tmpimg = QImage(m_dst.data, m_dst.cols, m_dst.rows, static_cast(m_dst.step), QImage::Format_RGB888);
QImage tmpimg21 =tmpimg.copy();
m_tmpimageWidget->setImg(tmpimg21);
QSize size=QSize(m_dst.rows/2,m_dst.cols/2);
m_frame->setMaximumSize(size); m_frame->setMinimumSize(size);
}
void setImg(cv::Mat *matRGBinput ,int select)
{
setImg(* matRGBinput , select);
}
void setImg(cv::Mat matRGBinput ,int select)
{
cv::Mat matRGB=matRGBinput.clone();

int B,G,R;
for(int x=0;x(y, x)[0];
G = matRGB.at(y, x)[1];
B = matRGB.at(y, x)[2];

switch(select)
{
case 0:
R = matRGB.at(y, x)[0]=R;
G = matRGB.at(y, x)[1]=R;
B = matRGB.at(y, x)[2]=R;break;
case 1:
R = matRGB.at(y, x)[0]=G;
G = matRGB.at(y, x)[1]=G;
B = matRGB.at(y, x)[2]=G;break;
case 2:
R = matRGB.at(y, x)[0]=B;
G = matRGB.at(y, x)[1]=B;
B = matRGB.at(y, x)[2]=B;break;
}
}
QImage tmpimg = QImage(matRGB.data, matRGB.cols, matRGB.rows, static_cast(matRGB.step), QImage::Format_RGB888);
QImage tmpimg1 =tmpimg.copy();
m_tmpimageWidget->setImg(tmpimg1);
QSize size=QSize(matRGB.rows/2,matRGB.cols/2);
qDebug()<parent;
m_frame->setMaximumSize(size);m_frame->setMinimumSize(size);

}
private:
QFrame *m_frame;
QGridLayout *m_gridLayout;

QWidget *parent;
};


使い方は 例えば UIで置いた フレームが
ui->frame_myLogo
frame_myLogo_R
frame_myLogo_G
frame_myLogo_B

UIでは フレームとてけとに置きます
frames.png
セレクションされてるのは フレームです 全部で取り敢えず 8つ 置いたよみたいなレベルです。

これに レナちゃんのいれて RGB に分解してそれぞれ表示します。
動作は 鈍いです。

RGBlena.png



setWindowTitle("Test OpenCV");
cv::Mat src = loadFromQtResouce(":/img/Lenna.png");
if(src.empty()) {qDebug() << "Failed to open image file.";Q_ASSERT(0); }

cv::Mat srcRGB;
LoadImg2UIFrameWithSetting_QGridLayoutToFrame *Canny=new LoadImg2UIFrameWithSetting_QGridLayoutToFrame(ui->frame_myLogo_Canny ,this);
srcRGB=Canny->BGR2RGB(src);/////////////////とりあえず RGBの順番揃える。
Canny->setCanny(src);
LoadImg2UIFrameWithSetting_QGridLayoutToFrame *RGB=new LoadImg2UIFrameWithSetting_QGridLayoutToFrame(ui->frame_myLogo ,this);
RGB->setImg(srcRGB,3);
LoadImg2UIFrameWithSetting_QGridLayoutToFrame *R=new LoadImg2UIFrameWithSetting_QGridLayoutToFrame(ui->frame_myLogo_R ,this);
LoadImg2UIFrameWithSetting_QGridLayoutToFrame *G=new LoadImg2UIFrameWithSetting_QGridLayoutToFrame(ui->frame_myLogo_G ,this);
LoadImg2UIFrameWithSetting_QGridLayoutToFrame *B=new LoadImg2UIFrameWithSetting_QGridLayoutToFrame(ui->frame_myLogo_B ,this);
R->setImg(srcRGB,0);
G->setImg(srcRGB,1);
B->setImg(srcRGB,2);



カメラを取り込みをやってみましょう。


 
馬鹿のひとつおぼえ 4 カメラは スレッドで起動します

カメラを メインで 無限ループさせるのは 辛いので
 しかたなく スレッド起動します。
 
馬鹿のひとつおぼえ 5 スレッドはQスレッド Qobject を 

 Qオブジェクトに プログラムをいれて
  moveToThread  で 起動します。
 なんだかわからないけど これで スレッドが起動します。
 終わる時に 順序よく 消さないといけないので いい方法わかりません。
 とりあえず
CamCaptureObj  でカメラを 取るプログラムのクラスだとします これは後述します。


m_CamCaptureObj = new CamCaptureObj();//// これは カメラキャプチャのクラスですが これを つくって
m_thread = new QThread(this);///////// スレッド をつくって
m_CamCaptureObj->moveToThread(m_thread);//// スレッドを移動します。 あとでスタートします。

connect(m_thread , SIGNAL(started()) , m_CamCaptureObj , SLOT(process()));////// スレッドをスタートしたら プロセスというサブルーチンを呼びます。
connect(m_CamCaptureObj , SIGNAL(frameUpdateed()) , this , SLOT(on_frameUpdateed()));// 画像が更新されたら  という信号をとります。

connect(m_CamCaptureObj , SIGNAL(processEnd()) , m_thread , SLOT(quit())); /// キャプチャーが終了したら スレッドは 停止させる
connect(m_thread , SIGNAL(finished()) , m_thread , SLOT(deleteLater()));///スレッドが終了したら スレッドを消す
connect(m_CamCaptureObj , SIGNAL(processEnd()) , m_CamCaptureObj , SLOT(deleteLater()));///スレッドが終了したら オブジェクトを消す


frameRGB=new LoadImg2UIFrameWithSetting_QGridLayoutToFrame(ui->frame_ORG,this);///これは UIのフレームにレアうと置いて というクラス
frameR=new LoadImg2UIFrameWithSetting_QGridLayoutToFrame(ui->frame_R,this);
frameG=new LoadImg2UIFrameWithSetting_QGridLayoutToFrame(ui->frame_G,this);
frameB=new LoadImg2UIFrameWithSetting_QGridLayoutToFrame(ui->frame_B,this);

QImage t0=QImage(":/img/Lenna.png");//動作の最初のテストデ レイナ ねーちゃんを ロード
QImage t1=QImage(":/img/Lenna.png");//動作の最初のテストデ レイナ ねーちゃんを ロード
QImage t2=QImage(":/img/Lenna.png");//動作の最初のテストデ レイナ ねーちゃんを ロード
QImage t3=QImage(":/img/Lenna.png");//動作の最初のテストデ レイナ ねーちゃんを ロード

this->frameR->m_tmpimageWidget->setImg(t0);//動作の最初のテストデ それぞれ配置
frameG->m_tmpimageWidget->setImg(t1);//動作の最初のテストデ それぞれ配置
frameB->m_tmpimageWidget->setImg(t2);//動作の最初のテストデ それぞれ配置
frameRGB->m_tmpimageWidget->setImg(t3);//動作の最初のテストデ それぞれ配置


m_thread->start(); ////////////////////////////起動すると レイナネーちゃんはかき消されます



void MainWindow:: closeEvent(QCloseEvent * event)
{
m_CamCaptureObj->quit();///// クローズでキャプチャは停止させましょう。
QSettings setting("setting.ini", QSettings::IniFormat);// これも馬鹿のひとつおぼえ ウィンドウの形状をおぼえる
setting.setValue("geometry", saveGeometry());
setting.setValue("windowState", saveState());
QMainWindow::closeEvent(event);
}


void MainWindow::readSettings()///起動時に  サイズとか もどします。
{
QSettings setting("setting.ini", QSettings::IniFormat);
restoreGeometry(setting.value("geometry").toByteArray());
restoreState(setting.value("windowState").toByteArray());
}


MainWindow::~MainWindow()
{
qDebug()<<" m_thread->exit()";///////////ウインドウが本当に終了するとき スレッドをぬけましょう
m_thread->exit();
qDebug()<<" m_thread->wait()";
m_thread->wait();////////スレッドが消えるまでは我慢する。 こと
qDebug()<<"delete ui";
delete ui;
}

さて ここまでの起動してみましょう  キャプチャのクラスは もっと後述です 
 まずは 入れ物がこんな調子 


 ビデオのキャプチャスレッドが 画像を取り込むたびによばれます。
 とりあえず 1個だけアップデートします・
  だらしないですが m_frame はばプリックで 色をBGRから RGBに入れ替えて表示です。
void MainWindow::on_frameUpdateed()
{
cv::Mat tmp=frameRGB->BGR2RGB(m_CamCaptureObj->m_frame);
frameRGB->setImg(tmp,4);////RGB に色を変更して 
}

ふむふむ カメラが パジャマの 毛をうつしてる。 という話し
kamera.png



おはずかしいプログラムで まだバグだらけ でも
 cameracaptureobjは
 ヘッダ^はご想像あれ。 オブジェクトでつくってる。
 あと 細線化とか ループにいれている。
 本体が クローズしたら quit がよばれて ループが終了するようにしている。
 終了すると  最後に WINDOWのデストラクタで きえる。

LoadImg2UIFrameWithSetting_QGridLayoutToFrame で作られたインスタンスは 
きちんとデリートしましょう。 それいまほったらかし




こんな感じ
#include "camcaptureobj.h"
#include
extern int global_param[];


CamCaptureObj::CamCaptureObj(QObject *parent) : QObject(parent)
{

}

void CamCaptureObj::process()
{
qDebug()<<"doWork";
m_flgRunning=true;

VideoCapture cap;
cap.open(0);

if (!cap.isOpened())
{
qDebug() << "Can not open video stream: '";
return ;
}

Mat mono;

vector circles;

cv::Mat frame; //取得したフレーム
Detector detector;
cv::Mat calcframe;

cv::Mat canny_img;
int width=0;
int height=0;
while((cap.read(frame))&&(m_flgRunning==true))//無限ループ
{
cap >> frame;if (frame.empty()){cout << "Finished reading: empty frame" << endl;break;}
if(width!=frame.cols){width=frame.cols;framesizeUpdateed(width,height);}
if(height!=frame.rows){height=frame.rows;framesizeUpdateed(width,height);}

int64 t = getTickCount();
vector found = detector.detect(frame);
t = getTickCount() - t;


cvtColor( frame, mono, CV_BGR2GRAY );
Canny(mono, canny_img, global_param[4], global_param[5],3);
cv::HoughCircles(
canny_img, // 8ビット,シングルチャンネル,グレースケールの入力画像
circles, // 検出された円を出力.配列の [ 0, 1 ] に円の中心座標. [2] に円の半径が格納される
cv::HOUGH_GRADIENT, // cv::HOUGH_GRADIENT メソッドのみ実装されている.
global_param[0], // 画像分解能に対する出力解像度の比率の逆数
global_param[1], // 検出される円の中心同士の最小距離
global_param[2], // Canny() の大きいほうの閾値.勾配がこのパラメータを超えている場合はエッジとして判定
global_param[3] // Canny() の小さいほうの閾値.勾配がこのパラメータを下回っている場合は非エッジとして判定
);

m_Qcannyimg = QImage(canny_img.data, canny_img.cols, canny_img.rows, static_cast(canny_img.step), QImage::Format_Grayscale8);
cvtColor( canny_img, mono, CV_GRAY2RGB );
for( size_t i = 0; i < circles.size(); i++ )
{
Point center(cvRound(circles[i][0]), cvRound(circles[i][4]));
int radius = cvRound(circles[i][5]);
//qDebug()<0)&&(radius<400)){

circle( mono, center, 3, Scalar(255,255,0), -1, 8, 0 );
circle( mono, center, radius, Scalar(0,255,0), 3, 8, 0 );
}
}

{
ostringstream buf;
buf << "Mode: " << detector.modeName() << " ||| "
<< "FPS: " << fixed << setprecision(1) << (getTickFrequency() / (double)t);
putText(frame, buf.str(), Point(10, 30), FONT_HERSHEY_PLAIN, 2.0, Scalar(0, 0, 255), 2, LINE_AA);
}
for (vector::iterator i = found.begin(); i != found.end(); ++i)
{
Rect &r = *i;
detector.adjustRect(r);
rectangle(frame, r.tl(), r.br(), cv::Scalar(0, 255, 0), 2);
}
cv::cvtColor(mono, m_dist, CV_BGR2RGB); // OpenCVの命令でRGBの順番を入れ替えて、m_dstに保存
m_frame=frame.clone();
emit frameUpdateed();
}
qDebug()<<"processEnd";
emit processEnd();

};
void CamCaptureObj::quit()
{
qDebug()<<"quit";
m_flgRunning=false;
};
























 

2020年12月31日

CUDAで マッチングしてみた。 10倍遅くなった がっかり。オーバーヘッドだ。

動作チェックなので if 文でてけと
 チェックしたところ 


if(true) {

cv::cuda::GpuMat srcg;srcg.upload(Img_Ref);
cv::cuda::GpuMat tmplg(*tpl);tmplg.upload(*tpl);
cv::cuda:: GpuMat resultg;
auto matcher= cv::cuda:: createTemplateMatching(CV_8UC1,match_method[i] );// cv::TM_CCOEFF_NORMED);

matcher->match(srcg, tmplg,resultg);
tmplg.download( *tpl);
resultg.download(*result);
}
else
{
matchTemplate( Img_Ref, *tpl, *result, match_method[i] );
}




こっちは おそい GPU使ったほう 
filename= :/Image/shcd.png
filename= :/Image/shcd.png
filename= :/Image/shcd.png
filename= :/Image/shcd.png
elaped 323 ( 61.2307 , 62.9867 ) 314 ( 45.8407 , 58.4362 ) 321 ( 51.5852 , 59.97 ) 313 ( 64.7638 , 68.8308 ) 322 ms
OpenCV loading time:

CPUつかったほうの結果  速い
filename= :/Image/shcd.png
filename= :/Image/shcd.png
filename= :/Image/shcd.png
filename= :/Image/shcd.png
elaped 41 ( 61.2307 , 62.9867 ) 34 ( 45.8407 , 58.4362 ) 40 ( 51.5852 , 59.97 ) 40 ( 64.7638 , 68.8308 ) 33 ms
OpenCV loading time:



ビルド失敗してたので直した  

LIBS+=-L/usr/local/cuda/targets/x86_64-linux/lib
LIBS+=-L/usr/local/cuda/lib64

LIBS+=-lopencv_core
LIBS+=-lopencv_flann
LIBS+=-lopencv_imgproc
LIBS+=-lopencv_imgcodecs
LIBS+=-lopencv_videoio
LIBS+=-lopencv_highgui
LIBS+=-lopencv_ml
LIBS+=-lopencv_video
LIBS+=-lopencv_objdetect
LIBS+=-lopencv_features2d
LIBS+=-lopencv_calib3d
LIBS+=-lopencv_superres
LIBS+=-lopencv_cudaarithm
LIBS+=-lopencv_cudafilters
LIBS+=-lopencv_cudawarping
LIBS+=-lopencv_cudaimgproc
LIBS+=-lopencv_cudafeatures2d
LIBS+=-lopencv_cudaoptflow
LIBS+=-lopencv_cudabgsegm
LIBS+=-lopencv_cudastereo
LIBS+=-lopencv_cudaobjdetect

リンクは こんな調子 で OK
 
  cv::cuda::GpuMat srcg;srcg.upload(Img_Ref);
cv::cuda::GpuMat tmplg(*tpl);tmplg.upload(*tpl);
cv::cuda:: GpuMat resultg;
などは 時間は1m程度だけど 最初に CUDAの アレヤコレヤロードしてるみたいだ。
 いざ ロードがおわると  CPUよ里速いのだが
 それしても 段取り時間がおおきする


 



2020年12月30日

OPENCV QT5 C++ matchTemplate マルチスレッド 解説 非GPUモード

shcd.jpg
あんまり需要はないだろうけど 
 マルチスレッド と アフィニティ とかの解説はあるが
 
 OPENVCV でマルチスレッドでのサンプルがないので自分のためだけ?に解説しておく
 あわよくばだれかの役にたてば 幸いです。

やりたいことは リアルタイム処理に近い方法で OPENCVをマルチスレッドでつかう
OS であるLINUXをすべてRAM上に配置
 マルチスレッドも マルチコアであることを意識して 並列化
 動作時間も計測 そんな チャンリンシャン な 話です。
 そんな需要にヒントになればいいなぁ ということです。



OPENCVなどのインストールや ビルドは 別途かきました 2020年12月21日
https://fanblogs.jp/computersettings/archive/16/0 とか です この前後  で
 カーネルビルドや ライブCDモディファイなど 高速化にいい話を書いています。
 私的には 素晴らしい(自画自賛)のめっちゃ読みにくい 日記です。


では 解説です。
 動作させるにあたり インクルードは
#include <opencv2/opencv.hpp>
#include <opencv2/core/cuda.hpp>
#include <opencv2/cudawarping.hpp>

 リンクは ビルドしたものを
LIBS+=/usr/local/lib64/libstdc++.so.6
LIBS+=-L/usr/local/lib64
LIBS+=-lpthread

LIBS+=/usr/local/lib64/libopencv_core.so
LIBS+=/usr/local/lib64/libopencv_highgui.so
LIBS+=/usr/local/lib64/libopencv_imgproc.so
LIBS+=/usr/local/lib64/libopencv_imgcodecs.so

LIBS+=/usr/local/lib64/libopencv_features2d.so
LIBS+=/usr/local/lib64/libopencv_flann.so
#LIBS+=/usr/local/lib64/libopencv_legacy.so
LIBS+=/usr/local/lib64/libopencv_ml.so
LIBS+=/usr/local/lib64/libopencv_objdetect.so
LIBS+=/usr/local/lib64/libopencv_photo.so
LIBS+=/usr/local/lib64/libopencv_stitching.so
LIBS+=/usr/local/lib64/libopencv_superres.so

LIBS+=/usr/local/lib64/libopencv_videoio.so


 な感じです。 まだ CUDAは起動できていませんが なんとかできるかなぁ?
 今日のところは 通常CPUでの マッチングどえす。

では解説です
 呼び出しは マッチングさせたい形を 登録します。
 QTの リソースにファイルをおいておき これを 読み込み という構造です。
呼び出しは スペード ダイアモンド クラブ ハート様 を ベクターにいれて

heart.png
club.png
diamond.png
spade.png


 自分が作った マッチングというクラス のインスタンスにいれます
 Matching は 
std::vector templates;
templates.push_back(":/Image/spade.png");
templates.push_back(":/Image/diamond.png");
templates.push_back(":/Image/club.png");
templates.push_back(":/Image/heart.png");
matching = new Matching(":/Image/shcd.png",templates);
matching->Disp(true);

delete matching;


shcd.jpg


いよいよこれらを あれします。そしてなにします。

Matching::Matching( std::string srcfilename, std::vector templatefilenames)
{ this->srcfilename=srcfilename;
Img_Ref =loadFromQrc(srcfilename.c_str() );
for(size_t i=0;i<templatefilenames.size();i++)
{
cv::Mat tml= loadFromQrc(templatefilenames.at(i).c_str() );
Img_templates.push_back(tml);
imshow(templatefilenames.at(i).c_str() , tml);
qDebug()<<" filename="<<srcfilename.c_str();
}

Img_Ref.copyTo( img_display );
Img_results.resize(templatefilenames.size());//画像の数 画像の大きさじゃないので勘違いなしで
mcs.resize(templatefilenames.size());
mythreads.resize(Img_templates.size());
this->laptimes.resize(Img_templates.size());
run();

 いよいよ これからはしらせる run() です なにがランなのかというと おおざっぱすぎるのですが
 ここで準備した ものを テンプレート関数に かけます
 もっとまともな名前がいいのですが・・・
 run のなかでは さらに マルチスレッドで _run() を ハート す・・・・ 4つハシラせます。
ちなみに ここの loadFromQrc は 
 Qtのリソースファイルを マットに変換している関数です。 OPENCVは qtのリソースなんかよめませんもん。
cv::Mat Matching::loadFromQrc(QString qrc, int flag)
{
//double tic = double(getTickCount());

QFile file(qrc);
cv::Mat m;
if(file.open(QIODevice::ReadOnly))
{
qint64 sz = file.size();
std::vector buf(sz);
file.read((char*)buf.data(), sz);
m = cv::imdecode(buf, flag);
return m;
}else
{

// double toc = (double(getTickCount()) - tic) * 1000.0 / getTickFrequency();
qDebug() << "OpenCV loading time: " ;

return m;
}
}


ランは アフィニティ設定 してます あってるのかな?
スレッドを起動して そのスレッドをプロセッサに割り付けます。
 あとは 時間計測です。


void Matching::run()
{
std::chrono::system_clock::time_point start, end; // 型は auto で可
start = std::chrono::system_clock::now(); // 計測開始時間
for( unsigned int i=0;i(i))->native_handle();
int rc = pthread_setaffinity_np( pth, sizeof(cpu_set_t), &cpuset);
if (rc != 0) {
std::cerr << "Error calling pthread_setaffinity_np: " <<rc << "\n";
}

}
for( unsigned int i=0;ijoin();mythreads.at(i)=nullptr; }
end = std::chrono::system_clock::now(); // 計測終了時間
double elapsed = std::chrono::duration_cast(end-start).count(); //処理に要した時間をミリ秒に変換
qDebug()<<"elaped "<< elapsed <<"("<<mcs.at(0).x<<","<<mcs.at(0).y<<")"
<<this->laptimes.at(0)<<" "
<<"("<<mcs.at(1).x<<","<<mcs.at(1).y<<")"<<this->laptimes.at(1)<<" "
<<"("<<mcs.at(2).x<<","<<mcs.at(2).y<<")"<<this->laptimes.at(2)<<" "
<<"("<<mcs.at(3).x<<","<<mcs.at(3).y<<")"<<this->laptimes.at(3)<<"ms";
}

  いよいよ あれです。 
動作試験なので いいかげんに match_method を4つ苦し紛れにつっこんでいます。
メンバーにしたほうがいいかもしれませんけどね
GPU は まだ使っていません。 やりかけみたいな そして まだGPU使い方
は 今日のところは知りません。 
おそらく  GPUに アップロードして おいて  マッチングして 取り出す みたいな
 話しです。それをこれから ネットで探します。 
GPU演算は 噂でオーバーヘッドがおおきいと聞いたからです。 ロードセーブする時間が必要でしょう。


int match_method[4];
void Matching::_run(int i)
{ std::chrono::system_clock::time_point start, end; // 型は auto で可
start = std::chrono::system_clock::now(); // 計測開始時間
cv::Mat * tpl = &this->Img_templates.at(static_cast(i));
cv::Mat *result =&this->Img_results.at(static_cast(i));

cv::cuda::GpuMat imgGpuSrc, imgGpuDst;
cv::cuda::GpuMat ImgGpu_Ref;
imgGpuSrc.upload(*tpl);
ImgGpu_Ref.upload(Img_Ref);

/// Create the result matrix
int result_cols = Img_Ref.cols - tpl->cols + 1;
int result_rows = Img_Ref.rows - tpl->rows + 1 ;
result->create( result_cols, result_rows, CV_32FC1 );
/// Do the Matching and Normalize
matchTemplate( Img_Ref, *tpl, *result, match_method[i] );
normalize( *result, *result, 0, 1, NORM_MINMAX, -1, Mat() );
/// Localizing the best match with minMaxLoc
double minVal; double maxVal; Point minLoc; Point maxLoc;
Point matchLoc;
minMaxLoc( *result, &minVal, &maxVal, &minLoc, &maxLoc, Mat() );
/// For SQDIFF and SQDIFF_NORMED, the best matches are lower values. For all the other methods, the higher the better
if( match_method[i] == cv::TM_SQDIFF || match_method[i] == cv::TM_SQDIFF_NORMED )
{ matchLoc = minLoc; }
else
{ matchLoc = maxLoc; }

rectangle( *result, matchLoc, Point( matchLoc.x + tpl->cols , matchLoc.y + tpl->rows ), Scalar::all(0), 2, 8, 0 );

Mat cut_img(Img_Ref,Rect(matchLoc.x,matchLoc.y,tpl->cols, tpl->rows));
Mat gray_img;
cvtColor(cut_img, gray_img,cv::COLOR_RGB2GRAY);
Moments mu = moments( gray_img, false );
Point2f mc = Point2f( mu.m10/mu.m00 , mu.m01/mu.m00 );
mcs.at(i)=mc;
circle( img_display,Point( matchLoc.x + mc.x , matchLoc.y + mc.y ), 4, Scalar(255,255,100), 2, 4);
rectangle( img_display, matchLoc, Point( matchLoc.x + tpl->cols , matchLoc.y + tpl->rows ), Scalar::all(0), 2, 8, 0 );
end = std::chrono::system_clock::now(); // 計測終了時間
double elapsed = std::chrono::duration_cast(end-start).count(); //処理に要した時間をミリ秒に変換
this->laptimes.at(i)=static_cast(elapsed);

}



表示がいいかげんになのですが 全体で46ミリ秒  ハード スペード ・・・ が
それぞれ 37 39 45 32 ミリ秒かかっています。
そして 4つのスレッドが すべて済んだら 全体がおわります。
  並列化の効果がでてるとみていいでしょう。 きっと
直列にすると 37+39+45+32になるはずですが 46ミリで終了してるらしいです。
 つっこみあったら お知らせください。
filename= :/Image/shcd.png
filename= :/Image/shcd.png
filename= :/Image/shcd.png
filename= :/Image/shcd.png
elaped 46 ( 61.2307 , 62.9867 ) 37 ( 45.8407 , 58.4362 ) 39 ( 51.5852 , 59.97 ) 45 ( 64.7638 , 68.8308 ) 32 ms
OpenCV loading time:
EXITTHREAD


 今日のこところは ここまでです。


 











2020年12月29日

opencv CUDAは動作チェック 

動作チェックパタンマッチ.png

今回は 4スレッドで パタンマッチを書いてみた。
解説は別途 動作試験したら 通常動作はしました
 まだ CUDAは 使っていません。 リンクはしていますが。。。

こんな雰囲気で 4つのパタンの マッチングをとって  その結果を表示する。
templates.push_back(":/Image/spade.png");
templates.push_back(":/Image/diamond.png");
templates.push_back(":/Image/club.png");
templates.push_back(":/Image/heart.png");

matching = new Matching(":/Image/shcd.png",templates);
matching->Disp(true);



void Matching::run()
{
std::chrono::system_clock::time_point start, end; // 型は auto で可
start = std::chrono::system_clock::now(); // 計測開始時間
for( unsigned int i=0;i(i))->native_handle();
int rc = pthread_setaffinity_np( pth, sizeof(cpu_set_t), &cpuset);
if (rc != 0) {
std::cerr << "Error calling pthread_setaffinity_np: " << rc << "\n";
}

}
for( unsigned int i=0;ijoin();mythreads.at(i)=nullptr; }
end = std::chrono::system_clock::now(); // 計測終了時間
double elapsed = std::chrono::duration_cast(end-start).count(); //処理に要した時間をミリ秒に変換
qDebug()<<"elaped "<< elapsed <<"("<laptimes.at(0)<<" ";
// <<"("<laptimes.at(1)<<" "
// <<"("<laptimes.at(2)<<" "
// <<"("<laptimes.at(3)<<"ms";
}


4つの スペード ハート クラブ ダイヤ 
パタンマッチして 重心にマルを書いてみた。



4つとも いっぺんに
filename= :/Image/shcd.png
filename= :/Image/shcd.png
filename= :/Image/shcd.png
filename= :/Image/shcd.png
elaped 43 ( 61.2307 , 62.9867 ) 35
OpenCV loading time:
EXITTHREAD


スペードだけ 
filename= :/Image/shcd.png
elaped 34 ( 61.2307 , 62.9867 ) 33
OpenCV loading time:
EXITTHREAD



うごいたので いいことにします。 



2020年12月28日

改めまして GCC cuda gforce1050ti driver opencv

https://www.nvidia.com/en-us/drivers/results/166883/ 1050TI  ドライバーダウンロード systemctl get-default ll /etc/systemd/system/default.target systemctl set-default multi-user.target もどすときは systemctl set-default graphical.target wget https://developer.download.nvidia.com/compute/cuda/11.1.1/local_installers/cuda_11.1.1_455.32.00_linux.run sudo sh cuda_11.1.1_455.32.00_linux.run git clone https://github.com/itseez/opencv.git git clone https://github.com/itseez/opencv_contrib.git で ゲットして mkdir build cd build  opencv にこんなコンフィグ
cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D OPENCV_EXTRA_MODULES_PATH=../../opencv_contrib/modules -D INSTALL_C_EXAMPLES=ON -D INSTALL_PYTHON_EXAMPLES=ON -D INSTALL_TESTS=ON -D WITH_PYTHON=ON -D BUILD_opencv_python2=OFF -D BUILD_opencv_python3=ON -D PYTHON_DEFAULT_EXECUTABLE=python3 -D WITH_MKL=ON -D WITH_CUDA=ON -D CUDA_FAST_MATH=ON -D WITH_CUBLAS=ON -D WITH_CUDNN=ON -D WITH_NVCUVID=OFF -D OPENCV_DNN_CUDA=OFF -D BUILD_opencv_cudaimgproc=OFF -D BUILD_EXAMPLES=ON -D WITH_TBB=ON -D WITH_V4L=ON -D WITH_OPENGL=ON -D CMAKE_C_COMPILER=/usr/local/bin/gcc ..

2020年12月25日

別のPCに QT5 インストールしてみる フェドラ33 カーネルメイクも一通りする。

趣味なので オープンソース版だ。
 アドレスは
https://www.qt.io/download-qt-installer?hsCtaTracking=7ac7660e-f6f1-4d80-ae94-772be5615b6c%7Ce1da64a4-2546-4fee-b31c-0c9d9eb85019
だと思う ここから ダウンロードして 
chmod +x chmod +x *.run
なんであれ 拡張子.run を 実行許可して ^^;
あとは あれしてナシにして 
 最新をインストールする。 6.0だ 

インストール中ひまなので FT232H使用USB⇔GPIO+SPI+I2C変換モジュール おさらい

ls /dev/gpiochip0 をすると 存在する 困った。
lsmod |grep ftd
ftdi_sio 65536 0

 やはり組み込まれているようだ。 

ダウンロードが済んだ

 gforce 1050ti のドライバもほしいし https://www.nvidia.com/en-us/geforce/drivers/
455.45 のバージョンらしい。









glibc 野良ビルドしてみた

 configur mkae だけじゃだめらしい
別ディレクトリから 
 たとえば mkdir build
cd build
../configure --disable-sanity-checks
make -j20
posted by 有象無象 at 21:52| Comment(0) | TrackBack(0) | C++

FT232H使用USB⇔GPIO+SPI+I2C変換モジュール root でしか動かない?

 
FT232H使用USB⇔GPIO+SPI+I2C変換モジュール を 非ルートユーザーで動作させようかな


ちょっとした オンオフをパソコンから行いたくてもIOがなく困っていたところ
 FT-232H 搭載の安価なボードがあったので
コレヲルートユーザー動作させてみました。 これで 例えばLEDの発光などが パソコンから制御できます。 QT5は C++の古典しかわからない人でも 画面が操作できるので 便利です。 
調べた内容は  FT-232Hの MPSSE
Multi-Protocol Synchronous Serial Engine
にあるGPIOです。
動作の条件は Fedora33 C++ Qt5で動かしてみました。
この手合は 買ってきてインストールでは root ユーザーでなければ動作しないことが多く
 例えばQt5のQTcreator でコンパイル実行では オープンエラーが発生します。
FT_OPEN FT_ERROR 帰ってきます。 root で起動するとうまく行きます。
 取り敢えず root で動作チェックをしたのち 通常ユーザで動作出来るようにしました。


dft232H.gif


目次
1ドライバのインストール 
   FT232H LINUXドライバインストール
2サンプルの GPIO 動作
   
通常ユーザーで動作させる

プログラムはみないでくださいな だってコンストラクタでいきなり エラーがでたらどうするんだみたいなプログラムだから 。  とりあえず動作する実験だから。 

 次のビデオは 実際ブレッドボードで 0から255まで 変化させてLED チカチカの実験だ。
 取り敢えず8ビットの IOができた。 プログラムは どっかにアップしておこうかと思うのだが 
 かっこわりープログラムです。

 

ドライバーのインストール


FT232H使用USB⇔GPIO+SPI+I2C変換モジュール
移動
https://www.ftdichip.com/Drivers/D2XX.htm
で 
tar xf libftd2xx-x86_64-1.4.8.gz

で展開  
README.txt に書かれている   普通みないもんなREADME ^^;

作業は ROOTユーザーになって から このファイルも /root/Documants に置いたなんてズボラーなんだ。
展開すると release になってるので あとで忘れるため 232Hとフォルダを変更した。

mv release FT232H
cp libftd2xx.so.1.4.8 /usr/local/lib
chmod 0755 /usr/local/lib/libftd2xx.so.1.4.8
ln -sf /usr/local/lib/libftd2xx.so.1.4.8 /usr/local/lib/libftd2xx.so


リードミーにあるとおりだが


cd examples
make -B    #これは無条件にメイクするという意味らしい。


いよいよ テストだ 


linux では いきなりでは失敗するらしい。 とりあえず EEPROM/

cd /root/Documents/FT232H/examples/EEPROM/read #スーパユーザのルートで 作業中^^;
lsmod |grep ftdi
既に先客あり  
[root@localhost read]# sudo rmmod ftdi_sio
[root@localhost read]# sudo rmmod usbserial
rmmod: ERROR: Module usbserial is builtin.

 マニュアル通りではない ビルトインされているらしい 
 カーネルのメイクが必要かもしれない
  ブラックリストに のせてロードされないようにする

[root@localhost read]# ./read
Library version = 0x10408
Opening port 0
FT_Open succeeded. Handle is 0xeeeba0
FT_GetDeviceInfo succeeded. Device is type 8.
FT_EE_Read succeeded.

Signature1 = 0
Signature2 = -1
Version = 0
VendorId = 0x0403
ProductId = 0x6014
Manufacturer = Adafruit
ManufacturerId = FT
Description = FT232H
SerialNumber = FT3ZQ7NY
MaxPower = 100
PnP = 1
SelfPowered = 0
RemoteWakeup = 0
Returning 0


EEROM 読めた

sudo rmmod usbserial

ところで
ところで私の 帽子はフェドラだ


とりあえず 私のフェドラは rmmod ftdi_sio してやらないと ぶつかる
 rmmod: ERROR: Module usbserial is builtin
ビルトイン されているらしい。
これは ブラックリストに のせてロードされないようにする。再起動が必要。
echo 'blacklist ftdi_sio' > /etc/modprobe.d/ftdi.conf こんな感じだ。

 
FT232H使用USB⇔GPIO+SPI+I2C変換モジュール を 非ルートユーザーで動作させる



まず su  酢で〆る
echo 'SUBSYSTEMS=="usb", ACTION=="add", MODE="0664", GROUP="usb"' >> /etc/udev/rules.d/99-usbftdi.rules/etc/init.d/udev reload
echo 'blacklist ftdi_sio' > /etc/modprobe.d/ftdi.conf
usermod -a -G usb $USER

こんな感じでリブートする。








2020年12月24日

opencv mat ---> QImage 変換

色がずれるので これだけ直して 表示だ エラーないという条件で 直球プログラムすると

 例えば qrcに登録したファイルなら

cv::Mat srcMat ,dstMat;
QFile file(":/img/Lenna.png");
qint64 sz = file.size(); std::vector buf(sz);
 file.read((char*)buf.data(), sz);
srcMat = cv::imdecode(buf, flag);



cv::cvtColor(srcMat, dstMat, CV_BGR2RGB); //bgr rgb 変換 そういう仕様なので勝てませんな
QImage Qimg = QImage(m_dst.data, m_dst.cols, m_dst.rows, static_cast(m_dst.step), QImage::Format_RGB888);

こんな感じで Qimg に変換されました。 

×

この広告は30日以上新しい記事の更新がないブログに表示されております。