■TL;DR
- gdb shellはpythonで機能強化できる
- OpenCVのMatを表示するpretty printerは公式配布!
- 色深度やチャネル数情報を簡単に確認できるようになる!
■はじめに:Matのflagsは人類にはまだ早かった!!
OpenCVのflagsには色々な情報が含まれている。OpenCV4の場合、こんな情報が色々含まれている。
| Bit | 意味 |
|---|---|
| 0-2 | ビット深度(Depth) |
| 3-11 | チャンネル数(Channels) |
| 14 | 連続性フラグ(Continuous) |
| 15 | サブ行列(Submatrix)フラグ |
なーんかうまく関数が読めない場合、これって色深度があってなかったり、チャネル数があってなかったりするわけですよ。しかし、例えばgdb上でprint srcとかすると意味不明な数字しか出てこなくて、わけわからんとなる。
// g++ main.cpp -o a.out -I/usr/local/include/opencv4 -lopencv_core -g -pg
#include <opencv2/core.hpp>
int main()
{
cv::Mat src0(cv::Size(320,240), CV_8UC1);
cv::Mat src1(cv::Size(240,160), CV_32FC3);
cv::Mat src2(cv::Size(5,5), CV_16SC4);
return 0;
}
こんな感じで、それぞれのMatには異なる色深度なんかを設定していると…
(gdb) p src0
$1 = {flags = 1124024320, dims = 2, rows = 240, cols = 320, data = 0x55555556de40 "",
datastart = 0x55555556de40 "", dataend = 0x555555580a40 "", datalimit = 0x555555580a40 "",
allocator = 0x55555556db60, u = 0x555555580a50, size = {p = 0x7fffffffdf58}, step = {
p = 0x7fffffffdfa0, buf = {320, 1}}}
(gdb) p src1
$2 = {flags = 1124024341, dims = 2, rows = 160, cols = 240, data = 0x7ffff6d8f040 "",
datastart = 0x7ffff6d8f040 "", dataend = 0x7ffff6dff840 "", datalimit = 0x7ffff6dff840 "",
allocator = 0x55555556db60, u = 0x555555580ac0, size = {p = 0x7fffffffdfb8}, step = {
p = 0x7fffffffe000, buf = {2880, 12}}}
(gdb) p src2
$3 = {flags = 1124024347, dims = 2, rows = 5, cols = 5, data = 0x555555580b40 "",
datastart = 0x555555580b40 "", dataend = 0x555555580c08 "", datalimit = 0x555555580c08 "",
allocator = 0x55555556db60, u = 0x555555580c50, size = {p = 0x7fffffffe018}, step = {
p = 0x7fffffffe060, buf = {40, 8}}}
絶望した!!こんな読みにくい可読性の低いflagsに絶望した!!
色深度もチャネル数も分からない!!なんなら、どっちが幅でどっちが高さかも分からない!
人類は、OpenCVのMatをデバッグできるようにはできていないんだ!!(極論)
■解決策:OpenCV公式のMat Pretty Printerがあります!
だが、絶望するのはまだ早い。実はOpenCVには公式に、Mat Pretty Printerが存在するのだ!!インストールはちょっと面倒だけど、使いこなす事で、確実にデバッグ力(ぢから)が向上できることは間違いない!!ええ、多分きっとそんな気がすることがたまにあります。
1⃣ mat_pretty_printerを手頃な位置にインストール
残念ながら自動インストールされないので、手動でコピー。
cd /usr/local/share/opencv4/
cp /home/kmtr/work/opencv4/samples/gdb/mat_pretty_printer.py .
2⃣ gdb shell内からsource
そしたら、今度はインストールしたスクリプトをgdb shellの中からsourceしよう!
(gdb) source /usr/local/share/opencv4/mat_pretty_printer.py
3⃣ (Option) 自動ロード設定
もし毎回 sourceするのが面倒ならば、 .gdbinitファイルにコマンドを書いておくと、gdb起動するたびに自動実行されます。
4⃣ 実際にMatを表示
もう flags が読める……。Matの色深度もチャネル数も分かる……
こんなに嬉しいことはない。僕には帰れる場所(デバッグ環境)があるんだ... fin
最早これは、gdbという素体にpythonというマグネット・コーティングして、3倍速のデバッグにも耐えられるようになったも同然ですね!!!
(gdb) p src0
$4 = {view_type = 0x555555581160 "CV_8UC1", view_is_continuous = true, view_is_submatrix = false,
view_size = 0x555555581180 "[240 320]",
view_data = 0x5555555811a0 "[[0 0 0 ... 0 0 0] [0 0 0 ... 0 0 0] [0 0 0 ... 0 0 0] ... [0 0 0 ... 0 0 0] [0 0 0 ... 0 0 0] [0 0 0 ... 0 0 0]]", flags = 1124024320, dims = 2, rows = 240, cols = 320,
data = 0x55555556de40 "", datastart = 0x55555556de40 "", dataend = 0x555555580a40 "",
datalimit = 0x555555580a40 "", allocator = 0x55555556db60, u = 0x555555580a50, size = {
p = 0x7fffffffdf58}, step = {p = 0x7fffffffdfa0, buf = {320, 1}}}
(gdb) p src1
$5 = {view_type = 0x555555581220 "CV_32FC3", view_is_continuous = true, view_is_submatrix = false,
view_size = 0x555555581240 "[160 240]",
view_data = 0x555555581260 "[[[0. 0. 0.] [0. 0. 0.] [0. 0. 0.] ... [0. 0. 0.] [0. 0. 0.] [0. 0. 0.]] [[0. 0. 0.] [0. 0. 0.] [0. 0. 0.] ... [0. 0. 0.] [0. 0. 0.] [0. 0. 0.]] [[0. 0. 0.] [0. 0. 0.] "..., flags = 1124024341, dims = 2, rows = 160, cols = 240,
data = 0x7ffff6d8f040 "", datastart = 0x7ffff6d8f040 "", dataend = 0x7ffff6dff840 "",
datalimit = 0x7ffff6dff840 "", allocator = 0x55555556db60, u = 0x555555580ac0, size = {
p = 0x7fffffffdfb8}, step = {p = 0x7fffffffe000, buf = {2880, 12}}}
(gdb) p src2
$6 = {view_type = 0x555555581480 "CV_16SC4", view_is_continuous = true, view_is_submatrix = false,
view_size = 0x5555555814a0 "[5 5]",
view_data = 0x5555555814c0 "[[[0 0 0 0] [0 0 0 0] [0 0 0 0] [0 0 0 0] [0 0 0 0]] [[0 0 0 0] [0 0 0 0] [0 0 0 0] [0 0 0 0] [0 0 0 0]] [[0 0 0 0] [0 0 0 0] [0 0 0 0] [0 0 0 0] [0 0 0 0]] [[0 0 0 0] "..., flags = 1124024347, dims = 2, rows = 5, cols = 5,
data = 0x555555580b40 "", datastart = 0x555555580b40 "", dataend = 0x555555580c08 "",
datalimit = 0x555555580c08 "", allocator = 0x55555556db60, u = 0x555555580c50, size = {
p = 0x7fffffffe018}, step = {p = 0x7fffffffe060, buf = {40, 8}}}
■課題:OpenCV5対応がまだできていない
ただ、残念ながらOpenCV5対応はまだできていなかったのである(2025/12/20)。
サポートしている色深度が圧倒的に足りなかったり、ビット配置が違っていたり・・・
でも、これってチャンスなのですよ!!
OSS開発に参加してみようかな?Pythonは分かるんだけどね?って方!!チャンスですよ!!大チャンスですね!!!ここはもう乗るしかない、このビッグウェーブに!!
■まとめ:Matの読み解く力を人類は手に入れた!
- gdb shellはpythonで機能強化できる
- OpenCVのMatを表示するpretty printerは公式配布!
- 色深度やチャネル数情報を簡単に確認できるようになる!
以上です、ありがとうございました。