プログラミング」カテゴリーアーカイブ

Mandelbox

サークルの新歓用にデモプログラムを作成しています.
Mandelboxのレンダリングデモを作る予定で,試しにC++とGLSLでレイマーチングのテストプログラムを作りました.

Mandelboxはマンデルブロ集合を3次元に拡張したようなフラクタル図形で,少ないデータ数で非常にユニークな絵が得られるため,近年のデモシーンで良く使われているそうです.
↓の動画を観るとどんなものかわかると思います.

取り敢えず,GLSLでレイマーチングで法線を計算してレンダリングしたのが↓です.
mandelbox01 mandelbox02
二枚目は近づきすぎて軽く表示がバグった状態なのですがなんかかっこいいので載せました.

ちょっとサークルの班の関係でプログラムはC#縛りになっているので,後でC#とSharpDXで描き直そうを思っています.

万有引力

なんとなく,引力のデモを書いてみました.
適当に万有引力の法則から数値微分してるだけです.

矩形検出

ちょっとやってみたい事があるので,その準備として画像中の矩形検出処理を書いてみました.処理手順は単純に

  1. 画像を2値化
  2. 輪郭線検出
  3. 輪郭線を近似して,四角形になっているか判定

のような感じです.
四角形かどうかの判定は4点かつ,面積が一定以上かどうかで判定しています.
追加で凸形になっているかを調べるともっといいかもしれません.

sq sq2
緑が検出された輪郭線.青がその中で矩形っぽいもの.

2014/03/20 ソースちょっと修正

/***************************
* 矩形検出
* @author : tetro
***************************/
#include <vector>
#include <sstream>
#include <iostream>
#include <opencv2/opencv.hpp>

/***************************
* main
***************************/
int main(){
	cv::VideoCapture cap(0);
	// esc を押すまで
	while (cv::waitKey(5) != 0x1b){
		cv::Mat frame;
		cap >> frame;
		// キャプチャできていなければ処理を飛ばす
		if (!frame.data){
			continue;
		}

		// 2値化
		cv::Mat grayImage, binImage;
		cv::cvtColor(frame, grayImage, CV_BGR2GRAY);
		cv::threshold(grayImage, binImage, 128.0, 255.0, CV_THRESH_OTSU);
		cv::imshow("bin", binImage);

		// 輪郭抽出
		std::vector< std::vector< cv::Point > > contours;
		cv::findContours(binImage, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
		// 検出された輪郭線の描画
		for (auto contour = contours.begin(); contour != contours.end(); contour++){
			cv::polylines(frame, *contour, true, cv::Scalar(0, 255, 0), 2);
		}

		// 輪郭が四角形かの判定
		for (auto contour = contours.begin(); contour != contours.end(); contour++){
			// 輪郭を直線近似
			std::vector< cv::Point > approx;
			cv::approxPolyDP(cv::Mat(*contour), approx, 50.0, true);
			// 近似が4線かつ面積が一定以上なら四角形
			double area = cv::contourArea(approx);
			if (approx.size() == 4 && area > 1000.0){
				cv::polylines(frame, approx, true, cv::Scalar(255, 0, 0), 2);
				std::stringstream sst;
				sst << "area : " << area;
				cv::putText(frame, sst.str(), approx[0], CV_FONT_HERSHEY_PLAIN, 1.0, cv::Scalar(0, 128, 0));
			}
		}
		cv::imshow("frame", frame);
	}
}

Raspberry piにDisplayLinkのUSBディスプレイを接続する

この間購入したRaspberry piにUSBディスプレイ(LCD-8000UD)を接続してみました.
イメージ作成環境はvirtualbox上の Ubuntu 12.10 で行いました.
以下設定手順.
続きを読む