PythonからSQLite3に保存した画像をC++ OpenCVでdecode
タイトルの日本語わかりにくくない?
ここでは画像はpng形式のものを使うことにします。適宜置き換えてください まずはPythonからsqlite3に画像を保存する。
import sqlite3 img_path = "hoge.png" # open image and write byte to blob with open(img_path, 'wb') as f: blob = f.read() conn = sqlite3.connect("huga.db") cur = conn.cursor() cur.execute("create table if not exists test(id int primary, data blob)") cur.execute(f"insert into test({blob})") conn.commit() cur.close() conn.close()
#include "sqlite3.h" #include <iostream> int main() { sqlite3* db; sqlite3_stmt* stmt; int ret = sqlite3_open("huga.db", &this->db); if (ret) { // failed sqlite3_close(db); return ; } ret = sqlite3_prepare_v2(this->db, "select * from test", -1, &this->stmt, nullptr); if (ret) { // failed sqlite3_finalize(stmt); sqlite3_close(db); return ; } unsigned char* blob = nullptr; int len = 0; while (SQLITE_ROW == (ret = sqlite3_step(this->stmt))) { len = sqlite3_column_bytes(this->stmt, 1); blob = (unsigned char*)sqlite3_column_blob(this->stmt, 1); std::vector<unsigned char> data(blob, blob + len); cv::Mat Image = cv::imdecode(data, 0); if (Image.empty()) continue; cv::imshow("a", Image); cv::waitKey(0); } sqlite3_finalize(stmt); sqlite3_close(db); }
おまけ
PythonからSQLite3にbyte配列を渡すときに注意したいのが
import numpy as np import cv2 img = cv2.imread("hoge.png") # または # img = np.full((10, 10), 0, 'uint8')みたいなとき blob = np.ndarray.tobytes(img)
これをそのままSQLite3に入れて取り出そうとすると配列の形式が違うためにクラッシュするので、
_, enc = cv2.imencode(".png", img)
blob = enc.tobytes()
こう書き換えてやるといい