#include "Feature_extraction.h"
//濃度特徴
cv::Mat Feature_extraction::Density_histgram(Raw_image<short>& ct, array3<unsigned int>& labeling, size_t labelcount)
{
//ヒストグラム作成 -100〜 1200;
auto r_Hist = std::vector<DensityData>(labelcount + 1);
for (int L = 1; L < labelcount + 1; L++) {
r_Hist[L].Hist = new int[1300];
r_Hist[L].NormalizeHist = new double[1300];
r_Hist[L].CPD = new double[1300];
for (int i = 0; i < 1300; i++) {
r_Hist[L].Hist[i] = 0;
r_Hist[L].NormalizeHist[i] = 0;
}
}
for (int i = 0; i < ct.data.VOXELS; i++) {
if (labeling[i] != 0) {
if (ct.image[i] < -100) {
r_Hist[labeling[i]].Hist[0] ++;
}
else if (ct.image[i] > 1199) {
r_Hist[labeling[i]].Hist[1299] ++;
}
else
r_Hist[labeling[i]].Hist[ct.image[i] + 100] ++;
if (ct.image[i] > r_Hist[labeling[i]].Max || r_Hist[labeling[i]].Max == -999) {
if (ct.image[i] < 1299)
r_Hist[labeling[i]].Max = ct.image[i];
else
r_Hist[labeling[i]].Max = 1299;
}
if (ct.image[i] < r_Hist[labeling[i]].Min || r_Hist[labeling[i]].Min == -999)
if (ct.image[i] > -100)
r_Hist[labeling[i]].Min = ct.image[i];
else
r_Hist[labeling[i]].Min = -100;
r_Hist[labeling[i]].HistVOXELS++;
}
}
for (int k = 1; k < labelcount + 1; k++) {
for (int i = 0; i < 1300; i++) {
if (i == 0 || i == 1299) {
r_Hist[k].NormalizeHist[i] = 0;
}
else {
r_Hist[k].NormalizeHist[i] = r_Hist[k].Hist[i] / (double)r_Hist[k].HistVOXELS;
}
if (i != 0)
r_Hist[k].CPD[i] += r_Hist[k].CPD[i - 1] + r_Hist[k].NormalizeHist[i];
else
r_Hist[k].CPD[i] = 0;
}
}
for (int k = 1; k < labelcount + 1; k++) {
r_Hist[k].Average = 0;
for (int i = 1; i < 1300; i++) {
r_Hist[k].Average += (i - 100) * r_Hist[k].Hist[i];
}
r_Hist[k].Average = r_Hist[k].Average / r_Hist[k].HistVOXELS;
}
for (int k = 1; k < labelcount + 1; k++) {
r_Hist[k].Variance = 0;
for (int i = 1; i < 1300; i++) {
r_Hist[k].Variance += (double)std::pow(((i - 100) - r_Hist[k].Average), 2) * r_Hist[k].NormalizeHist[i];
}
}
for (int k = 1; k < labelcount + 1; k++) {
r_Hist[k].Skewness = 0;
r_Hist[k].Kurtosis = 0;
for (int i = 1; i < 1300; i++) {
r_Hist[k].Skewness += (double)std::pow(((i - 100) - r_Hist[k].Average), 3) * r_Hist[k].NormalizeHist[i];
r_Hist[k].Kurtosis += (double)std::pow(((i - 100) - r_Hist[k].Average), 4) * r_Hist[k].NormalizeHist[i];
}
if (r_Hist[k].Variance == 0) {
r_Hist[k].Skewness = 0;
r_Hist[k].Kurtosis = 2;
}
else {
r_Hist[k].Skewness = r_Hist[k].Skewness / (double)std::pow(r_Hist[k].Variance, 1.5);
r_Hist[k].Kurtosis = r_Hist[k].Kurtosis / (double)std::pow(r_Hist[k].Variance, 2);
}
}
for (int k = 1; k < labelcount + 1; k++) {
delete[] r_Hist[k].CPD;
delete[] r_Hist[k].Hist;
delete[] r_Hist[k].NormalizeHist;
}
cv::Mat samples;
samples.create((int)labelcount, 7, CV_32F);
for (int i = 0; i < labelcount; i++) {
samples.at<float>(i, 0) = (float)r_Hist[i + 1].HistVOXELS;
samples.at<float>(i, 1) = (float)r_Hist[i + 1].Max;
samples.at<float>(i, 2) = (float)r_Hist[i + 1].Min;
samples.at<float>(i, 3) = (float)r_Hist[i + 1].Average;
samples.at<float>(i, 4) = (float)r_Hist[i + 1].Variance;
samples.at<float>(i, 5) = (float)r_Hist[i + 1].Skewness;
samples.at<float>(i, 6) = (float)r_Hist[i + 1].Kurtosis;
}
return (samples);
}
//テクスチャ特徴
array3<uchar> Feature_extraction::Histogram_equalization(Raw_image<short>& ct, int len)
{
//ヒストグラム作成 -100〜 1200;
array3<uchar> gets(ct.data.Width, ct.data.Height, ct.data.Depth, ct.data.reso, ct.data.reso, ct.data.reso, 0);
unsigned int* s_Hist = new unsigned int[1300];
unsigned int* s_CHist = new unsigned int[1300];
double s_VOXELS = 0;
uchar* FrattarHist = new uchar[1300];
//ヒストグラム平坦化
#pragma omp parallel for
for (int i = 0; i < 1300; i++) {
s_Hist[i] = 0;
s_CHist[i] = 0;
}
for (int i = 0; i < ct.data.VOXELS; i++) {
if (ct.image[i] < -100) {
s_Hist[0] ++;
}
else if (ct.image[i] > 1199) {
s_Hist[1299] ++;
}
else {
s_Hist[ct.image[i] + 100] ++;
s_VOXELS++;
}
}
for (int i = 0; i < 1300; i++) {
if (i == 0)
s_CHist[i] = 0;
else if (i == 1299)
s_CHist[i] = s_CHist[i - 1];
else
s_CHist[i] = s_CHist[i - 1] + s_Hist[i];
}
int Counta = -999;
for (int i = 0; i < 1300; i++) {
if (i == 0)
FrattarHist[i] = 0;
else if (i == 1299)
FrattarHist[i] = len - 1;
else if ((((double)s_CHist[i] / s_VOXELS * (double)len) - 1) < 0)
FrattarHist[i] = 0;
else
FrattarHist[i] = (uchar)(((double)s_CHist[i] / s_VOXELS * (double)len) - 1);
if (FrattarHist[i] < 0) {
FrattarHist[i] = 0;
}
if (Counta != FrattarHist[i]) {
Counta = FrattarHist[i];
}
}
#pragma omp parallel for
for (int i = 0; i < ct.data.VOXELS; i++) {
if (ct.image[i] < -100)
gets[i] = 0;
else if (ct.image[i] > 1199)
gets[i] = len - 1;
else
gets[i] = FrattarHist[ct.image[i] + 100];
}
delete[] s_Hist;
delete[] s_CHist;
delete[] FrattarHist;
return(gets);
}
cv::Mat Feature_extraction::GLCM(array3<uchar>& image, array3<unsigned int>& label, size_t& labelcount,int len)
{
std::vector<GLCMData> s_Sim(labelcount + 1);
array3<uchar> region(image.width(), image.height(), image.depth(), image.reso1(), image.reso1(), image.reso1(), 0);
array3<unsigned int> Labeling(image.width(), image.height(), image.depth(), image.reso1(), image.reso1(), image.reso1(), 0);
for (int i = 0; i < image.size(); i++) {
Labeling[i] = label[i];
if (label[i] != 0)
region[i] = 255;
}
//mist::erosion(region,2);
//for (int i = 0; i < Data.VOXELS; i++) {
// if (region[i] != 0)
// Labeling[i] = 0;
//}
int ImageSize = image.width() * image.height();
//構造要素の生成
int FilterStructure[27];
int StructureCount = 0;
for (int dz = -1; dz <= 1; dz++) {
for (int dy = -1; dy <= 1; dy++)
for (int dx = -1; dx <= 1; dx++) {
FilterStructure[StructureCount] = ImageSize * dz + image.width() * dy + dx;
StructureCount++;
}
}
int pass = ((3 * 3 * 3) / 2);
for (int k = 0; k < labelcount + 1; k++) {
s_Sim[k].simMatrinx = new float* [len];
s_Sim[k].Q = new float* [len];
for (int i = 0; i < len; i++) {
s_Sim[k].simMatrinx[i] = new float[len];
s_Sim[k].Q[i] = new float[len];
}
}
for (int k = 0; k < labelcount + 1; k++) {
for (int i = 0; i < len; i++)
for (int j = 0; j < len; j++) {
s_Sim[k].simMatrinx[i][j] = 0;
s_Sim[k].Q[i][j] = 0;
}
}
//同時生起行列計算
for (int z = 1; z < image.depth() - 1; z++)
for (int y = 1; y < image.height() - 1; y++)
for (int x = 1; x < image.width() - 1; x++) {
int point = ImageSize * z + y * image.width() + x;
if (Labeling[point] != 0) {
for (int i = 0; i < 27; i++) {
if (i != pass) {
s_Sim[Labeling[point]].MatrixCount++;
s_Sim[Labeling[point]].simMatrinx[image[point]][image[point + FilterStructure[i]]] ++;
}
}
}
}
for (int k = 1; k < labelcount + 1; k++) {
for (int i = 0; i < len; i++)
for (int j = 0; j < len; j++) {
s_Sim[k].simMatrinx[i][j] = s_Sim[k].simMatrinx[i][j] / s_Sim[k].MatrixCount;
}
}
//特徴量抽出処
for (int k = 1; k < labelcount + 1; k++) {
s_Sim[k].Py = new float[len];
s_Sim[k].Pxsy = new float[len];
s_Sim[k].Px = new float[len];
s_Sim[k].Pxpy = new float[2 * len - 1];
}
//初期化
for (int k = 1; k < labelcount + 1; k++) {
for (int j = 0; j < len; j++) {
s_Sim[k].Py[j] = 0;
s_Sim[k].Px[j] = 0;
s_Sim[k].Pxsy[j] = 0;
}
}
for (int k = 1; k < labelcount + 1; k++) {
for (int j = 0; j < 2 * len - 1; j++) {
s_Sim[k].Pxpy[j] = 0;
}
}
for (int k = 1; k < labelcount + 1; k++) {
for (int i = 0; i < len; i++)
for (int j = 0; j < len; j++) {
s_Sim[k].Py[i] += s_Sim[k].simMatrinx[j][i];
s_Sim[k].Px[i] += s_Sim[k].simMatrinx[i][j];
s_Sim[k].Pxpy[i + j] += s_Sim[k].simMatrinx[i][j];
s_Sim[k].Pxsy[abs(i - j)] += s_Sim[k].simMatrinx[i][j];
}
}
//全14種
//1.角度の二次モーメント
for (int k = 1; k < labelcount + 1; k++) {
for (int i = 0; i < len; i++)
for (int j = 0; j < len; j++) {
s_Sim[k].ASM += pow(s_Sim[k].simMatrinx[i][j], 2);
}
}
for (int k = 1; k < labelcount + 1; k++) {
for (int i = 0; i < len; i++)
s_Sim[k].DASM += pow(s_Sim[k].Pxsy[i], 2);
}
//2.コントラスト
for (int k = 1; k < labelcount + 1; k++) {
for (int i = 0; i < len; i++) {
s_Sim[k].Contrast += i * i * s_Sim[k].Pxsy[i];
}
}
//3.相関
for (int k = 1; k < labelcount + 1; k++) {
for (int i = 0; i < len; i++) {
s_Sim[k].Ax += i * s_Sim[k].Px[i];
s_Sim[k].Ay += i * s_Sim[k].Py[i];
}
}
for (int k = 1; k < labelcount + 1; k++) {
for (int i = 0; i < len; i++) {
s_Sim[k].Sx += pow(i - s_Sim[k].Ax, 2) * s_Sim[k].Px[i];
s_Sim[k].Sy += pow(i - s_Sim[k].Ay, 2) * s_Sim[k].Py[i];
}
}
for (int k = 1; k < labelcount + 1; k++) {
for (int i = 0; i < len; i++)
for (int j = 0; j < len; j++) {
s_Sim[k].Correlation += i * j * s_Sim[k].simMatrinx[i][j] - s_Sim[k].Ax * s_Sim[k].Ay;
}
if (s_Sim[k].Sx * s_Sim[k].Sy != 0)
s_Sim[k].Correlation = s_Sim[k].Correlation / (s_Sim[k].Sx * s_Sim[k].Sy);
}
//4.分散
for (int k = 1; k < labelcount + 1; k++) {
for (int i = 0; i < len; i++)
for (int j = 0; j < len; j++) {
s_Sim[k].Variance += pow(i - s_Sim[k].Ax, 2) * s_Sim[k].simMatrinx[j][i];
}
}
//5.差分モーメント
for (int k = 1; k < labelcount + 1; k++) {
for (int i = 0; i < len; i++)
for (int j = 0; j < len; j++) {
s_Sim[k].IDM += (float)(1 / (1 + pow(i - j, 2))) * s_Sim[k].simMatrinx[j][i];
}
}
//6.平均
for (int k = 1; k < labelcount + 1; k++) {
for (int i = 0; i < 2 * len - 1; i++)
s_Sim[k].SAverage += i * s_Sim[k].Pxpy[i];
}
//7.分散
for (int k = 1; k < labelcount + 1; k++) {
for (int i = 0; i < 2 * len - 1; i++)
s_Sim[k].SVariance += pow(i - s_Sim[k].SAverage, 2) * s_Sim[k].Pxpy[i];
}
//8.合計エントロピー
for (int k = 1; k < labelcount + 1; k++) {
for (int i = 0; i < 2 * len - 1; i++) {
if (s_Sim[k].Pxpy[i] > 0) {
s_Sim[k].SEntropy += s_Sim[k].Pxpy[i] * log2(s_Sim[k].Pxpy[i]);
}
}
s_Sim[k].SEntropy = s_Sim[k].SEntropy * -1;
}
//9.エントロピー
for (int k = 1; k < labelcount + 1; k++) {
for (int i = 0; i < len; i++)
for (int j = 0; j < len; j++) {
if (s_Sim[k].simMatrinx[j][i] > 0) {
s_Sim[k].Entropy += s_Sim[k].simMatrinx[j][i] * log2(s_Sim[k].simMatrinx[j][i]);
}
}
s_Sim[k].Entropy = s_Sim[k].Entropy * -1;
}
//差平均
for (int k = 1; k < labelcount + 1; k++) {
for (int i = 0; i < len; i++)
s_Sim[k].SAvey += i * s_Sim[k].Pxsy[i];
}
//10.差分散
for (int k = 1; k < labelcount + 1; k++) {
for (int i = 0; i < len; i++)
s_Sim[k].DVariance += pow(i - s_Sim[k].SAvey, 2) * s_Sim[k].Pxsy[i];
}
//11.差エントロピー
for (int k = 1; k < labelcount + 1; k++) {
for (int i = 0; i < len; i++)
if (s_Sim[k].Pxsy[i] > 0) {
s_Sim[k].DEntropy += s_Sim[k].Pxsy[i] * log2(s_Sim[k].Pxsy[i]);
}
s_Sim[k].DEntropy = s_Sim[k].DEntropy * -1;
}
//12.IMOC1
for (int k = 1; k < labelcount + 1; k++) {
for (int i = 0; i < len; i++)
if (s_Sim[k].Px[i] > 0) {
s_Sim[k].HX += s_Sim[k].Px[i] * log2(s_Sim[k].Px[i]);
}
s_Sim[k].HX = s_Sim[k].HX * -1;
}
for (int k = 1; k < labelcount + 1; k++) {
for (int i = 0; i < len; i++)
if (s_Sim[k].Py[i] > 0)
s_Sim[k].HY += s_Sim[k].Py[i] * log2(s_Sim[k].Py[i]);
s_Sim[k].HY = s_Sim[k].HY * -1;
}
for (int k = 1; k < labelcount + 1; k++) {
for (int i = 0; i < len; i++)
for (int j = 0; j < len; j++) {
if (s_Sim[k].Px[j] * s_Sim[k].Py[i] > 0)
s_Sim[k].HXY1 += s_Sim[k].simMatrinx[j][i] * log2(s_Sim[k].Px[j] * s_Sim[k].Py[i]);
}
s_Sim[k].HXY1 = s_Sim[k].HXY1 * -1;
}
for (int k = 1; k < labelcount + 1; k++) {
for (int i = 0; i < len; i++)
for (int j = 0; j < len; j++) {
if (s_Sim[k].Px[j] * s_Sim[k].Py[i] > 0)
s_Sim[k].HXY2 += s_Sim[k].Px[j] * s_Sim[k].Py[i] * log2(s_Sim[k].Px[j] * s_Sim[k].Py[i]);
}
s_Sim[k].HXY2 = s_Sim[k].HXY2 * -1;
}
for (int k = 1; k < labelcount + 1; k++) {
double MAX = s_Sim[k].HX > s_Sim[k].HY ? s_Sim[k].HX : s_Sim[k].HY;
if (MAX != 0)
s_Sim[k].IMOC1 = (s_Sim[k].Entropy - s_Sim[k].HXY1) / (float)MAX;
else
s_Sim[k].IMOC1 = 0;
}
//13.IMOC2
for (int k = 1; k < labelcount + 1; k++) {
s_Sim[k].IMOC2 = (float)pow(1 - exp(-2.0 * (s_Sim[k].HXY2 - s_Sim[k].Entropy)), 0.5);
}
//14.MCC
for (int k = 1; k < labelcount + 1; k++) {
for (int i = 0; i < len; i++) {
for (int j = 0; j < len; j++) {
for (int s = 0; s < len; s++) {
if (s_Sim[k].Px[i] * s_Sim[k].Py[j] > 0)
s_Sim[k].Q[i][j] += s_Sim[k].simMatrinx[i][s] * s_Sim[k].simMatrinx[s][j] / (s_Sim[k].Px[i] * s_Sim[k].Py[j]);
}
if (s_Sim[k].Q[i][j] > s_Sim[k].Mf || s_Sim[k].Mf == -999) {
if (s_Sim[k].Mn == -999) {
s_Sim[k].Mf = s_Sim[k].Q[i][j];
s_Sim[k].Mn = s_Sim[k].Q[i][j];
}
else {
s_Sim[k].Mn = s_Sim[k].Mf;
s_Sim[k].Mf = s_Sim[k].Q[i][j];
}
}
}
}
}
for (int k = 1; k < labelcount + 1; k++) {
s_Sim[k].MCC = (float)pow(s_Sim[k].Mn, 0.5);
}
cv::Mat samples;
samples.create((int)labelcount, 16, CV_32F);
for (int i = 0; i < labelcount; i++) {
samples.at<float>(i, 0) = (float)s_Sim[i + 1].ASM;
samples.at<float>(i, 1) = (float)s_Sim[i + 1].Contrast;
samples.at<float>(i, 2) = (float)s_Sim[i + 1].Correlation;
samples.at<float>(i, 3) = (float)s_Sim[i + 1].Variance;
samples.at<float>(i, 4) = (float)s_Sim[i + 1].IDM;
samples.at<float>(i, 5) = (float)s_Sim[i + 1].SAverage;
samples.at<float>(i, 6) = (float)s_Sim[i + 1].SVariance;
samples.at<float>(i, 7) = (float)s_Sim[i + 1].SEntropy;
samples.at<float>(i, 8) = (float)s_Sim[i + 1].Entropy;
samples.at<float>(i, 9) = (float)s_Sim[i + 1].DVariance;
samples.at<float>(i, 10) = (float)s_Sim[i + 1].DEntropy;
samples.at<float>(i, 11) = (float)s_Sim[i + 1].IMOC1;
samples.at<float>(i, 12) = (float)s_Sim[i + 1].IMOC2;
samples.at<float>(i, 13) = (float)s_Sim[i + 1].MCC;
samples.at<float>(i, 14) = (float)s_Sim[i + 1].DASM;
samples.at<float>(i, 15) = (float)s_Sim[i + 1].SAvey;
}
for (int k = 0; k < labelcount + 1; k++) {
for (int i = 0; i < len; i++) {
delete[] s_Sim[k].simMatrinx[i];
delete[] s_Sim[k].Q[i];
}
delete[] s_Sim[k].simMatrinx;
delete[] s_Sim[k].Q;
delete[] s_Sim[k].Px;
delete[] s_Sim[k].Py;
delete[] s_Sim[k].Pxpy;
delete[] s_Sim[k].Pxsy;
}
return samples;
}
//勾配特徴
cv::Mat Feature_extraction::Laplace_feature(Raw_image<short>& ct, array3<unsigned int>& label, size_t& labelcount)
{
mist::array3<short> CT(ct.data.Width, ct.data.Height, ct.data.Depth, ct.data.reso, ct.data.reso, ct.data.reso, ct.image, ct.data.VOXELS);
mist::array3<float> CTb, laplace;
mist::gaussian_filter(CT, CTb);
mist::laplacian_filter(CTb, laplace);
auto r_Hist = std::vector<Extravasation_detect::LabelData>(labelcount + 1);
for (int i = 0; i < ct.data.VOXELS; i++)
if (label[i] != 0) {
r_Hist[label[i]].Area++;
r_Hist[label[i]].CTValue += laplace[i];
}
for (int i = 1; i < labelcount+ 1; i++) {
r_Hist[i].CTValue = r_Hist[i].CTValue / r_Hist[i].Area;
}
cv::Mat samples;
samples.create((int)labelcount, 1, CV_32F);
for (int i = 0; i < labelcount; i++) {
samples.at<float>(i, 0) = (float)r_Hist[i + 1].CTValue;
}
return (samples);
}
//Matの操作
cv::Mat Feature_extraction::MatLink(cv::Mat& firstMat, cv::Mat& secondMat)
{
if (firstMat.rows != secondMat.rows) {
printf("サンプル数が等しくありません\n");
return cv::Mat();
}
int Firstcol = firstMat.cols;
int Secondcol = secondMat.cols;
cv::Mat samples;
samples.create(firstMat.rows, firstMat.cols + secondMat.cols, CV_32F);
for (int i = 0; i < firstMat.rows; i++) {
for (int k = 0; k < Firstcol + Secondcol; k++) {
if (k < Firstcol)
samples.at<float>(i, k) = (float)firstMat.at<float>(i, k);
else
samples.at<float>(i, k) = (float)secondMat.at<float>(i, k - Firstcol);
}
}
return samples;
}
cv::Mat Feature_extraction::Addsample(cv::Mat& firstMat, cv::Mat& secondMat)
{
if (firstMat.cols != secondMat.cols) {
printf("特徴量数が等しくありません.F:%d S:%d\n", firstMat.cols, secondMat.cols);
return cv::Mat();
}
cv::Mat samples;
samples.create(firstMat.rows + secondMat.rows, firstMat.cols, CV_32F);
for (int i = 0; i < firstMat.rows + secondMat.rows; i++) {
for (int k = 0; k < firstMat.cols; k++) {
if (i < firstMat.rows)
samples.at<float>(i, k) = (float)firstMat.at<float>(i, k);
else
samples.at<float>(i, k) = (float)secondMat.at<float>(i - firstMat.rows, k);
}
}
return samples;
}
cv::Mat Feature_extraction::LabelMat(cv::Mat& input, int Label)
{
cv::Mat samples;
samples.create(input.rows, input.cols + 1, CV_32F);
for (int i = 0; i < input.rows; i++) {
for (int k = 0; k < input.cols + 1; k++) {
if (k == 0)
samples.at<float>(i, k) = (float)Label;
else
samples.at<float>(i, k) = (float)input.at<float>(i, k - 1);
}
}
return samples;
}
//スケーリング
void Feature_extraction::Scaling(cv::Mat& feature)
{
double mean[24] = { 1272.082474,228.1726804,46.04896907,136.4137956
,1591.962119,0.013715459,2.886998773,0.023232985,40.59967549,-222509.8116,55.82264455,
0.35392532,99.37873564,105.9691725,4.644675446,6.800864593,23.03388621,3.277484601,-0.114886773,0.755248402,0.494389606,
0.158205928,3.749504322,-84.98969072 };
double std[24] = { 4743.678168,105.5522472,39.9497129,47.78214929,2334.156954,0.454731201,0.919405181,0.020641736,35.97252044,1303192.787,
45.77337404,0.116288456,9.207859944,99.59759599,0.674429203,1.190320582,18.6302418,0.624693816,0.038442077,0.087941346,
0.095944749,0.066310616,1.87270045,59.92641447 };
for (int i = 0; i < feature.rows; i++) {
auto p = feature.row(i).ptr<float>(0);
for (int j = 0; j < feature.cols; j++) {
p[j] = (p[j] - mean[j]) / std[j];
}
}
}
//スクリーニング
cv::Mat Feature_extraction::Screening(cv::Mat& samples)
{
int rows = samples.rows;
int count = 0;
std::vector<cv::Mat> s;
for (int i = 0; i < rows; i++) {
if (samples.at<float>(i, 0) >= 15) {
count++;
s.push_back(samples.row(i).clone());
}
}
cv::Mat Return;
Return.create(count, samples.cols, CV_32F);
for (int i = 0; i < count; i++) {
for (int j = 0; j < samples.cols; j++) {
Return.at<float>(i, j) = s[i].at<float>(0, j);
}
}
return Return;
}
//すべての特徴を一つのマットに保存する関数
cv::Mat Feature_extraction::All_feature_exstract(Raw_image<short> ct, array3<unsigned int>& label, size_t& labelcount, int len)
{
auto HE = Histogram_equalization(ct, len);
cv::Mat SimMat = GLCM(HE, label, labelcount,len);
cv::Mat DensityMat = Density_histgram(ct, label, labelcount);
cv::Mat FestureMat = MatLink(DensityMat, SimMat);
cv::Mat laplaceMat = Laplace_feature(ct, label, labelcount);
FestureMat = MatLink(FestureMat, laplaceMat);
FestureMat = Screening(FestureMat);
Scaling(FestureMat);
return FestureMat;
}
//学習データの正解特徴と誤検出特徴の数の調整
cv::Mat Feature_extraction::Feature_Cut(cv::Mat& samples, bool shafful, float Falserate)
{
int Label0 = 0;
int Label1 = 0;
for (int i = 0; i < samples.rows; i++) {
if (samples.at<float>(i, 0) == 1) {
Label1++;
}
else {
Label0++;
}
}
int Falsenum;
if (Falserate == -1) {
Falsenum = Label0;
}
else
Falsenum = (int)(Label1 * Falserate);
printf("Label1:%d,Label0:%d\n", Label1, Label0);
cv::Mat TrueMat, FalseMat;
TrueMat.create(Label1, samples.cols, CV_32F);
FalseMat.create((int)(Falsenum), samples.cols, CV_32F);
int TCount = 0;
int FCount = 0;
int Rate = (int)(Label0 / Label1 / Falserate);
printf("発生Rate:%d\n", Rate);
std::random_device rnd; // 非決定的な乱数生成器を生成
std::mt19937 mt(rnd()); // メルセンヌ・ツイスタの32ビット版、引数は初期シード値
std::uniform_int_distribution<> rand100(0, Rate - 1);
for (int i = 0; i < samples.rows; i++) {
if (samples.at<float>(i, 0) == 1) {
if (TCount < Label1) {
for (int k = 0; k < samples.cols; k++) {
TrueMat.at<float>(TCount, k) = samples.at<float>(i, k);
}
TCount++;
}
}
else {
if (Falserate == -1) {
if (FCount < FalseMat.rows) {
for (int k = 0; k < samples.cols; k++) {
FalseMat.at<float>(FCount, k) = samples.at<float>(i, k);
}
FCount++;
}
}
else {
if (rand100(mt) < 5) {
if (FCount < FalseMat.rows) {
for (int k = 0; k < samples.cols; k++) {
FalseMat.at<float>(FCount, k) = samples.at<float>(i, k);
}
FCount++;
}
}
}
}
}
printf("選定結果:1:%d,0:%d\n", TCount, FCount);
cv::Mat Return = Addsample(TrueMat, FalseMat);
std::random_device rnda; // 非決定的な乱数生成器を生成
std::mt19937 mta(rnda()); // メルセンヌ・ツイスタの32ビット版、引数は初期シード値
std::uniform_int_distribution<> randes(0, Return.rows - 1); // [0, 99] 範囲の一様乱数
if (shafful) {
printf("シャッフル開始\n");
for (int i = 0; i < Return.rows; i++) {
int randres = randes(mta);
cv::Mat tmp = Return.row(randres).clone();
cv::Mat tmp1 = Return.row(i).clone();
for (int k = 0; k < Return.cols; k++) {
Return.at<float>(i, k) = tmp.at<float>(0, k);
Return.at<float>(randres, k) = tmp1.at<float>(0, k);
}
}
}
return Return;
}
//学習したモデルを用いての分類
array3<uchar> Feature_extraction::Predict(cv::Ptr<cv::ml::RTrees> r_tree, array3<unsigned int>& label, size_t& labelcount, cv::Mat samples)
{
float* mtest = new float[labelcount + 1];
float* test = new float[labelcount + 1];
for (int k = 1; k < labelcount + 1; k++) {
cv::Mat sam = samples.row(k - 1).clone();
cv::Mat bsam = samples.row(k - 1).clone();
mtest[k] = r_tree->predict(sam, cv::noArray(), cv::ml::StatModel::RAW_OUTPUT);
mtest[k] = mtest[k] / 1000;
if (mtest[k] > 0.4) {
test[k] = 1;
}
else
test[k] = 0;
}
array3<uchar> s(label.width(), label.height(), label.depth(), 0.5, 0.5, 0.5, 0);
#pragma omp parallel for
for (int i = 0; i < label.size(); i++) {
if (label[i] != 0) {
if (test[label[i]] == 0) {
s[i] = 0;
}
else {
s[i] = 255;
}
}
}
delete[] mtest;
delete[] test;
return (s);
}
//CSVの入出力
void Feature_extraction::writeCSV(char* FileName, cv::Mat samples)
{
FILE* file;
fopen_s(&file, FileName, "w");
int row = samples.rows;
int col = samples.cols;
for (int i = 0; i < row; i++) {
for (int k = 0; k < col; k++) {
fprintf(file, "%f", samples.at<float>(i, k));
if (k != col)
fprintf(file, ",");
}
fprintf(file, "\n");
}
fclose(file);
}
Feature_extraction::CSVData Feature_extraction::readCSV(char* dataset)
{
char c[10000];
char* c1;
char* ends;
char s[] = " ,\n";//カンマ、スペース、改行
/*ファイルオープン*/
FILE* fp;
if ((fp = fopen(dataset, "r")) == NULL) {
printf("Can't open file.\n");
abort();
}
std::vector<std::vector<float>> TS;
//1行分を文字列としてcに読み込む
while ((fgets(c, sizeof(c), fp)) != NULL) {
//c1にカンマ、スペース、改行で区切った文字列を代入
c1 = strtok(c, s);
std::vector<float> GTS;
while (c1 != NULL) {
//TSにc1の文字列をdoubleに型変換して代入
GTS.push_back((float)strtod(c1, &ends));
//NULL文字で終わり
c1 = strtok(NULL, s);
}
TS.push_back(GTS);
}
fclose(fp);
int cols = (int)TS[0].size();
int rows = (int)TS.size();;
printf("rows:%d,cols%d\n", rows, cols);
CSVData Res;
Res.Labels.create(rows, 1, CV_32SC1);
Res.samples.create(rows, cols - 1, CV_32F);
for (int k = 0; k < rows; k++) {
for (int i = 0; i < cols; i++) {
if (i == 0) {
Res.Labels.at<float>(k, 0) = TS[k][0];
}
else {
Res.samples.at<float>(k, i - 1) = TS[k][i];
}
}
}
return Res;
}