CTA算法-各向异性测度-Conditional Texture Anisotropy

CTA算法
Conditional Texture Anisotropy
Roli 提 出 了 各 向 异 性 测 度 ( Conditional Texture Anisotropy, CTA) 的概念和计算原理, Nguyen 提出了各向异性测度的具体计算方法
选取某个像素的灰度,计算4个方向的P值,再计算CTA,然后把CTA从[0,1]映射到[0,255],生成灰度图,便于观察。
A是原图,B是灰度图

CTA算法-各向异性测度-Conditional Texture Anisotropy_第1张图片在这里插入图片描述

X是一个向量,由(均值,方差)组成。

在这里插入图片描述m 和 σ 分别为整张图像的深度均值和标准差;
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
CTA算法-各向异性测度-Conditional Texture Anisotropy_第2张图片
j表示4个方向,每个方向产生一条线,当成一个向量,线上有2d+1个像素,计算他们的P值

沿中心像素的 0°、45°、90° 和 135° 四个方向
L2为裂缝点,l1非裂缝点

CTA算法-各向异性测度-Conditional Texture Anisotropy_第3张图片
裂缝的某个方向的P值会与其他方向的P值有很大的差距,使得CTA的值接近1,
非裂缝则是4个方向大致一样,使CTA接近0.

在这里插入图片描述
把4个P中的最大和最小值选出来计算CTA。
CTA算法-各向异性测度-Conditional Texture Anisotropy_第4张图片
自己的代码测试效果图
上干货代码:(需要opencv 3.5以上版本)
CTA_function.cpp

#include "pch.h"
#include 
#include  "math.h"
#include 
#include
#include
#include "opencv2/opencv.hpp"
#include 
#include 
#include 
#include 
#include "CTA_function.h"
using namespace  std;
using namespace cv;
/*
	计算每一个像素点的CTA
*/
/*
	求均值,0度
	X(rows)动,Y不动
 */
float fun_sum_1(pixel px1, int d, Mat pic) {
	int i, j;
	i = px1.x, j = px1.y;
	float sum = 0;
	int start, end;
	start = i - d; end = i + d;
	if (start < 0) {
		start = 0;
	}
	if (end > pic.rows - 1) {
		end = pic.rows - 1;
	}
	int temp;
	int count = 0;
	while (start <= end) {
		int move = start;
		temp = (int)pic.at(move, j);//pic[move][j];
		sum = temp + sum;
		start++;
		count++;
	}
	return (float)sum / count;
}
/*
	135度
	X增Y增
*/
float fun_sum_2(pixel px1, int d, Mat pic) {
	int i, j, x_start, y_start;
	i = px1.x, j = px1.y;
	float sum = 0;
	int count = 0;
	x_start = i - d, y_start = j - d;

	for (int temp = 0; temp < 2 * d + 1; temp++) {
		int _x = x_start + temp;
		int _y = y_start + temp;
		if (_x<0 || _y<0 || _x>pic.rows - 1 || _y>pic.cols - 1)continue;
		sum = sum + (int)pic.at(_x, _y);//(int)pic.at(_x,_y);
		count++;
	}
	return sum / count;
}

/*
 求均值,90度,
 */
float fun_sum_3(pixel px1, int d, Mat pic) {
	int i, j;
	i = px1.x, j = px1.y;
	float sum = 0;
	int start, end;
	start = j - d; end = j + d;
	if (start < 0) {
		start = 0;
	}
	//cout << "end=" << end;
	if (end > pic.cols - 1) {
		//	cout << "end=" << end;
		end = pic.cols - 1;
	}
	//cout << "pic=" << (int)pic.at(i,j) << endl;
	int temp; int count = 0;
	//cout << "start=" << start << endl;
	while (start <= end) {
		int move = start;
		temp = (int)pic.at(i, move);//pic[i][move];
		sum = temp + sum;
		start++;
		count++;
	}
	return (float)(sum / (count));
}
/*
	45度
	X增Y减
*/
float fun_sum_4(pixel px1, int d, Mat pic) {
	int i, j, x_start, y_start;
	float sum = 0;
	int count = 0;
	i = px1.x, j = px1.y;
	x_start = i - d, y_start = j + d;
	for (int temp = 0; temp < 2 * d + 1; temp++) {
		int _x = x_start + temp;
		int _y = y_start - temp;
		if (_x<0 || _y<0 || _x>pic.rows - 1 || _y>pic.cols - 1) continue;
		sum = sum + (int)pic.at(_x, _y);
		count++;
	}
	return sum / count;
}
/*
  差的平方的求和,0度
  X动,Y不动
 */
float fun_dif_1(pixel px1, int d, float mean, Mat pic) {
	int i, j, x_start, y_start;
	i = px1.x, j = px1.y;

	float sum = 0;
	int count = 0;
	x_start = i - d, y_start = j;
	for (int temp = 0; temp < 2 * d + 1; temp++) {
		int _x = x_start + temp;
		int _y = y_start;
		if (_x<0 || _y<0 || _x>pic.rows - 1 || _y>pic.cols - 1) continue;
		sum = sum + ((int)pic.at(_x, _y) - mean)*((int)pic.at(_x, _y) - mean);
		count++;
	}
	return sum;
}
/*
  差的平方的求和,45度
  X增Y增
 */
float fun_dif_2(pixel px1, int d, float mean, Mat pic) {
	int i, j, x_start, y_start;
	float sum = 0;
	i = px1.x, j = px1.y;
	x_start = i - d, y_start = j - d;
	for (int temp = 0; temp < 2 * d + 1; temp++) {
		int _x = x_start + temp;
		int _y = y_start + temp;
		if (_x<0 || _y<0 || _x>pic.rows - 1 || _y>pic.cols - 1)continue;
		sum = sum + ((int)pic.at(_x, _y) - mean)*((int)pic.at(_x, _y) - mean);
	}
	return sum;
}
/*
  差的平方的求和,90度
  X不动,Y动
 */
float fun_dif_3(pixel px1, int d, float mean, Mat pic) {
	///////////////////////////////
	int i, j, x_start, y_start;
	float sum = 0;
	i = px1.x, j = px1.y;
	x_start = i, y_start = j - d;
	for (int temp = 0; temp < 2 * d + 1; temp++) {
		int _x = x_start;
		int _y = y_start + temp;
		if (_x<0 || _y<0 || _x>pic.rows - 1 || _y>pic.cols - 1) continue;
		sum = sum + ((int)pic.at(_x, _y) - mean)*((int)pic.at(_x, _y) - mean);
	}
	///////////////////////////////
	return sum;
}
/*
  差的平方的求和,135度
  X增,Y减
 */
float fun_dif_4(pixel px1, int d, float mean, Mat pic) {
	/////////////////////////////
	int i, j, x_start, y_start;
	float sum = 0;
	i = px1.x, j = px1.y;
	x_start = i - d, y_start = j + d;
	for (int temp = 0; temp < 2 * d + 1; temp++) {
		int _x = x_start + temp;
		int _y = y_start - temp;
		if (_x<0 || _y<0 || _x>pic.rows - 1 || _y>pic.cols - 1)continue;
		sum = sum + ((int)pic.at(_x, _y) - mean)*((int)pic.at(_x, _y) - mean);
	}
	////////////////////////////
	return sum;
}
/*
	标准差
*/
float fun_dif(float means, Mat pic) {
	float sum = 0;
	for (int i = 0; i < pic.rows; i++) {
		for (int j = 0; j < pic.cols; j++) {
			float temp = (float)((int)pic.at(i, j)) - means;
			sum = sum + (temp*temp);
		}

		return sqrt(sum);
	}
}
//ok
float fun_means(Mat pic) {
	int row = pic.rows;
	int col = pic.cols;
	float means = 0;
	for (int i = 0; i < row; i++) {
		for (int j = 0; j < col; j++)
		{
			int grayvalue = (int)pic.at(i, j);
			means = means + (float)grayvalue / (row*col);
		}
	}
	return means;
}

float fun_p(float mean1, float stdev1, float means, float stdev)
{
	float D, deta;
	D = sqrt(means*means + stdev * stdev);
	deta = sqrt((means - mean1)*(means - mean1) + (stdev - stdev1) * (stdev - stdev1));
	return ((D - deta) / deta);
}
float fun_CTA(pixel px1, int d, Mat pic) {
	int row = pic.rows;
	int col = pic.cols;
	float cta_num;
	//生成均值//ok
	float means, stdev;//全局的均值和方差
	means = fun_means(pic);
	//生成标准差
	stdev = fun_dif(means, pic);
	//生成4个方向向量
	float mean1, stdev1;//0度的均值和方差
	float mean2, stdev2;//45度
	float mean3, stdev3;//90度
	float mean4, stdev4;//135度

	mean1 = fun_sum_1(px1, d, pic) / (2 * d + 1);
	stdev1 = sqrt(fun_dif_1(px1, d, mean1, pic));//求方差
	//计算每个向量的P()
	//float  p1, p2, p3, p4;
	mean2 = fun_sum_2(px1, d, pic) / (2 * d + 1);
	stdev2 = sqrt(fun_dif_2(px1, d, mean1, pic));
	mean3 = fun_sum_3(px1, d, pic) / (2 * d + 1);
	stdev3 = sqrt(fun_dif_3(px1, d, mean1, pic));
	mean4 = fun_sum_4(px1, d, pic) / (2 * d + 1);
	stdev4 = sqrt(fun_dif_4(px1, d, mean1, pic));
	float p[4];
	p[0] = fun_p(mean1, stdev1, means, stdev);
	p[1] = fun_p(mean2, stdev2, means, stdev);
	p[2] = fun_p(mean3, stdev3, means, stdev);
	p[3] = fun_p(mean4, stdev4, means, stdev);
	//找min和max
	float min, max;
	std::sort(p, p + 4);
	min = p[0];
	max = p[3];
	cta_num = (max - min) / max;
	return cta_num;
}
/*
	映射[0,1]->[0,255]
*/
int Projection01to0255(float cta) {
	int grey = 0;
	grey = (int)(cta * 256);
	return grey;
}

 Mat CTA(Mat inPut, int distance) {
	Mat source = inPut;//图片路径
	Mat gray;
	cvtColor(source, gray, COLOR_RGB2GRAY, 1);
	Mat CTA_image(gray.rows, gray.cols, CV_8UC1);
	cvtColor(source, CTA_image, COLOR_BGR2GRAY, 1);
	pixel p1;
	p1.x = 0;
	p1.y = 0;
	for (int i = 0; i < gray.rows ; ++i)
		for (int j = 0; j < gray.cols ; ++j)
		{	float cta_num;
			p1.x = i; p1.y = j;
			cta_num = fun_CTA(p1, 10, gray);
			int gray = Projection01to0255(cta_num);
			CTA_image.at(i, j) = cta_num;
		}
	return CTA_image;
}

 void test()
 {
	 cout << "cta test" << endl;
 }

CTA_function.h

#include "pch.h"
#include 
#include  "math.h"
#include 
#include
#include
#include "opencv2/opencv.hpp"
#include 
#include 
#include 
#include 
using namespace  std;
using namespace cv;
typedef struct
{
	int x;
	int y;
}pixel;
float fun_sum_1(pixel px1, int d, Mat pic);
float fun_sum_2(pixel px1, int d, Mat pic);
float fun_sum_3(pixel px1, int d, Mat pic);
float fun_sum_4(pixel px1, int d, Mat pic);
float fun_dif_1(pixel px1, int d, float mean, Mat pic);
float fun_dif_2(pixel px1, int d, float mean, Mat pic);
float fun_dif_3(pixel px1, int d, float mean, Mat pic);
float fun_dif_4(pixel px1, int d, float mean, Mat pic);
float fun_dif(float means, Mat pic);
float fun_means(Mat pic);
float fun_p(float mean1, float stdev1, float means, float stdev);
float fun_CTA(pixel px1, int d, Mat pic);
int Projection01to0255(float cta);
Mat CTA(Mat inPut,int distance) ;
void test();

之后发现,计算速度很慢,又进行了多线程的优化,是原来的2.5倍速(笑)。
这里给出文件:
CTA_function_thread.cpp
最后,引用论文是
【Automatic Detection and Classification of Defect on road Pavement using Anisotropy Measure】 Tien Sy Nguyen, Manuel Avila, St´ephane Begot

你可能感兴趣的:(硕士阶段)