モチベーション
Jeff氏のNon-Circular Packingの絵がかっこよかった.
https://ippsketch.com/posts/non-circular-packing/
アルゴリズム改変して遊びたかったけど配列走査する画像処理はさすがにやりたくなかったのでOpenCVをProcessingに導入しようとした.
OpenCV for Processingのリポジトリは↓なのだが, 2017年から更新が止まっていて,対応してるOpenCVのバージョンも2.4.5止まりなので新しいOpenCV使うには生のOpenCV Java APIを叩くしかなかった.
https://github.com/atduskgreg/opencv-processing
Processingで外部jarファイルを利用する方法
最新のOpenCVは以下のページからダウンロード可能:
Windows環境でOpenCV Java APIを使うのに必要なのは以下の2ファイル
(4xx
のところはバージョンが入る):
build/java/opencv-4xx.jar
build/java/x64/opencv_java4xx.dll
OpenCVのjarとdllに適当にパス通してから以下のimport文を書いて実行
import org.opencv.core.*;
すると以下のようなエラーが出る.
Libraries must be installed in a folder named 'libraries' inside the sketchbook folder (see the Preferences window).
エラーの指示通りにlibraries
にjarファイルとdllを置いてもエラーになる.
どうやらエラー文が間違ってるらしく,正しくはcode
に置かないといけない.なんでやねん.
http://nlaboratory.blogspot.com/2009/12/processing.html
OpenCVで画像を読み込んでPImageに変換して出力するプログラム
画像は以下のスケッチから拝借した:
https://openprocessing.org/sketch/1190911
import org.opencv.core.*;
Mat img;
PImage pimg;
PGraphics pg;
static{ System.loadLibrary(Core.NATIVE_LIBRARY_NAME); }
void setup() {
size(800, 800);
// 画像をBGRAで読み込む
// (Imgcodecs.IMREAD_UNCHANGEDをつけないとBGRになるので注意)
img = Imgcodecs.imread(dataPath("banana_peeled.png"), Imgcodecs.IMREAD_UNCHANGED);
pimg = matToPImage(img);
}
void draw() {
background(100);
translate(width / 2.0, height / 2.0);
imageMode(CENTER);
rotate(frameCount / 60.0 * TWO_PI);
image(pimg, 0, 0);
}
PImage matToPImage(Mat mat) {
PImage img = new PImage(mat.cols(), mat.rows(), ARGB);
byte[] buff = new byte[mat.cols() * mat.rows() * 4];
mat.get(0, 0, buff);
img.loadPixels();
for (int k = 0; k < buff.length; k+=4) {
// ピクセルの順序をBGRAからARGBに並べ替える
int b = (buff[k+2] & 0xff) << 16;
int g = (buff[k+1] & 0xff) << 8;
int r = (buff[k] & 0xff) << 0;
int a = (buff[k+3] & 0xff) << 24;
// Matは要素数(width * height * 4)の配列に8bit整数としてBGRAの色情報を入れてる
// PImageは要素数(width * height)の配列に32bit整数としてARGBの色の情報を入れてる
img.pixels[k / 4] = a | r | g | b;
}
img.updatePixels();
return img;
}
void keyPressed() {
if (key == ESC) {
exit();
}
}
最後に
Mat -> PImage変換が重いのでこのままだとあんまり役に立たないかも.もっと高速にできそうな方法は見つけてるのでそのうち試すかもしれない.