OpenCVでマンデルブロ集合を描く実験
こちらの記事を見て、マンデルブロ集合は意外に短いコードで描ける事を知りOpenCVの勉強を兼ねて表示させてみました。
開発環境は、こちらの記事を見てVisual Studio 2022を使用。
OpenCVには、点を描画する専用の関数はなさそうだった為、こちらの記事を見てポインタを使用。全部調べて組み合わせただけですね。
以下タイトルの画像を表示させたコードです。
ポインタが使いやすい様にxとyのループの順番を入れ替えて、計算回数の偶数奇数の色分けを追加してみました。
// マンデルブロ集合 v002 (1000 x 1000pix, 計算回数50, 計算回数を偶数奇数で色分け)
#include <opencv2/opencv.hpp>
#include <iostream>
int main(void)
{
// 定数データ
double size = 4; // 描く領域の一辺の長さ
int pixel = 1000; // 描く領域の一辺のピクセル数
int kaisuu = 50; // 計算回数
// 変数データ
double x, y, a, b, _a, _b;
//空の画像生成(1000ピクセルの正方形の画像)
cv::Mat image = cv::Mat::zeros(cv::Size(pixel, pixel), CV_8UC3);
// マンデルブロ集合を描く
for (int j = 0; pixel > j; j++) { // y(虚部)方向のループ
y = j * size / pixel - size / 2; // 定数Cの虚部
cv::Vec3b *src = image.ptr<cv::Vec3b>(j); //j行目の先頭画素のポインタを取得
for (int i = 0; pixel > i; i++) { // x(実部)方向のループ
x = i * size / pixel - size / 2; // 定数Cの実部
a = 0; // くり返し計算に使う複素数zの実部
b = 0; // くり返し計算に使う複素数zの虚部
for (int k = 0; kaisuu > k; k++) { // 上限を50回とするくり返し計算
_a = a * a - b * b + x; // z^2+Cの計算(実部)
_b = 2 * a * b + y; // z^2+Cの計算(虚部)
a = _a; // zの値を更新(実部)
b = _b; // zの値を更新(虚部)
if (a * a + b * b > 4) { // もし絶対値が2を(絶対値の2乗が4を)超えていたら
//src[i] = cv::Vec3b(255, 0, 0); // (i,j)の位置のピクセルを「マンデルブロ集合でない色」で塗りつぶして
if ((k & 0x01) == 0) src[i] = cv::Vec3b(255, 0, 0); // 偶数(青色)
else src[i] = cv::Vec3b(0, 127, 127); // 奇数(黄色)
break; // 次の点の計算へ
}
}
}
}
//画像の表示
cv::imshow("showing",image);
cv::waitKey(0);
return 0;
}
今回は以上になります。
この記事が気に入ったらサポートをしてみませんか?