断層画像の座標系変換プログラム(平面の断層画像→球殻の断層画像) Ver. 0.1

断層画像の座標系変換プログラム(平面の断層画像→球殻の断層画像) Ver. 0.1

山椒魚
山椒魚 (ID3679) 2017/10/23
0

Twitterみてると、需要がありようだったので作った

https://twitter.com/BalavoineLab/status/918437202748690432
ここみてると、断層画像(平面の積層)を、球殻の積層(って言えば良いのだろうか)の断層画像のに変換したいという人が居たので、作った。

各層ごとに 
平面→球殻の座標変換を行っている。
バージョンは適当にVer. 0.1とする。

//OpenCV 3.1, Visual Studio 2013 
#include <string>
#include <iostream>
#include <vector>
#include <opencv2\core\core.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2/opencv_lib.hpp>
#include <cmath>

using namespace cv;
using namespace std;


double projection(double x, double y, double r, double a, double b, double c){
	double z;

	//z = c - sqrt(-y ^ 2 + 2 * b*y - x ^ 2 + 2 * a*x + r ^ 2 - b ^ 2 - a ^ 2);
	double D = -y*y + 2 * b*y - x *x+ 2 * a*x + r*r - b*b - a*a;
	if (D >= 0){
		z = c + sqrt(D);
	}
	else{ z = 0; }
	return z;
}



int main(int argc, const char* argv[])
{

	vector<Mat> stack;
	double z,cr;
	double a = 0, b = 0, c = 0;
	imreadmulti("onion.tif", stack, IMREAD_GRAYSCALE);
	double layer = 0;
	double maxl = stack.size();
	vector<Mat> dst;
	char s[256];
	Mat base = stack[0];

	Mat temp(Size(base.cols, base.rows), CV_8UC1, Scalar(0, 0, 0));
	for (std::vector<Mat>::iterator it = stack.begin(); it != stack.end(); ++it) {
		int r = base.cols / 2;
		layer = std::distance(stack.begin(), it);



		a = base.rows / 2;
		b = base.rows / 2;
		//unsigned char *p = &temp.at<uchar>(0, 0);
		for (int y = 0; y < base.rows; y++){
			for (int x = 0; x < base.cols; x++){
				//cr = (maxl - layer)*r / maxl;
				cr = layer*r / maxl;
				z = projection(x, y, cr, a, b, c);
				if (z > 0){ //printf("z=%lf, layer=%lf\n",z,z/(r/maxl));
				int zd =(int) z / (r / maxl);
				temp.at<uchar>(y,x) = stack[zd].at<uchar>(y,x);
				}
				else{ temp.at<uchar>(y, x) = 0; }
				

			}
			printf("test");
		}//1枚終了
		imshow("result", stack[layer]);
		imshow("temp", temp);
		int num = (int)layer;
		sprintf_s(s, "%d.png", num);

		imwrite(s, temp);
		printf("layer =%lf\n", layer);
		cv::waitKey(0);	}


	cv::namedWindow("result", cv::WINDOW_AUTOSIZE);


	//全てのウィンドウを閉じる
	cv::destroyAllWindows();

	return 0;
}

※投稿されたファイルについて、当社は一切責任を負いません。
DMM.make利用規約に同意の上、自己の責任でダウンロードしてください。

Result

left:After conversion, right:before conversion

詳しい解説は後日追記する。

参考にしてくれた記事

記事が登録されていません。
この記事を参考にして、新しく記事を投稿しよう!

違反について