暑假作了关于标准图像轮廓的人眼注视点与显著性的相关工作,以下主要写基于标准图像轮廓(人工勾画的)的显著性分析思路及实现过程,并与标准人眼注视点及其生成的显著图(可以理解为GroundTruth)进行对比。

一 工作目的

显著性分析一直是图像处理和计算机视觉领域的比较受欢迎的研究方向,而最近几年计算机视觉发展迅猛,这其中,深度学习扮演着特殊角色。但是,就如一些专家所言,深度学习有其自身的缺陷(虽然效果极好):没有很好的可解释性。于是想着,从生物视觉机制出发,从认知角度进行分析,对图像显著性进行建模和计算。篇幅有限,只记录大致思路。从国内外学者关于视觉机制的文章中可以了解到,生物尤其是人,对视觉机制的分析总结出三个层次的视觉显著性计算思路 :

(1)底层特征:包括图像的颜色、纹理、亮度、方向梯度等

(2)中层特征:目标特征

(3)高层特征:场景特征

结合Bottom-up的数据驱动方式和Top-down的任务驱动方式,对场景图像进行显著性分析和计算(具体思路不便透露)

二 基于标准图像轮廓的显著性和标准人眼注视点分析

1)给定一个图像和对应的标准轮廓数据集,以及对应的人眼注视点数据集(一 一对应,如图1),建立模型,计算图像的显著图,并与Ground-Truth人眼注视点对比。

  

图1:原RGB图           标准轮廓图        人眼注视点图        显著图(GT)       效果图

2)模型和方法

利用知觉组织理论中的格式塔原理建立模型

@1 Gestalt原理:

格式塔心理学诞生于1912年,是由德国心理学家组成的研究小组试图解释人类视觉的工作原理。他们观察了许多重要的视觉现象并对它们编订了目录。其中最基础的发现是人类视觉是整体的:我们的视觉系统自动对视觉输入构建结构,并在神经系统层面上感知形状、图形和物体,而不是只看到互不相连的边、线和区域。“形状”和“图形”在德语中是Gestalt,因此这些理论也称做视觉感知的格式塔原理。格式塔理论明确地提出:眼脑作用是一个不断组织、简化、统一的过程,正是通过这一过程,才产生出易于理解、协调的整体。具体而言,包括:

△1:图形与背景

△2:接近

△3:相似

△4:闭合

△5:连续

△6:简单

△7:均衡

以下图片来自网络,侵删。

接近性(Proximity):“距离上相近的物体容易被知觉组织在一起。”

图2:接近性

图2中我们会自分类,看成三个横行,四个竖列,没人会看成全是横行或竖列

连续性(Continuity):“凡具有连续性或共同运动方向的刺激容易被看成一个整体。”

图3:连续性

连续性原理,即是说我们的视觉倾向于感知连续的形式而不是离散的碎片,如图3

我们会将图像理解为一个大写的U和一个连续的单词而不是单一零碎的细小的其他图像。

相似性(Similarity):“我们的眼睛很容易关注那些外表相似的物体,且不管它们的位置是不是相邻,总是把它们联系起来”

图3:相似性

格式塔原理相似性原理指出了影响我们感知分组的另一个因素:如果其他的因素相同,那么相似的物体看起来归属于同一组,如图3中,我们会按照形状、大小、色彩的相似性进行图像中目标的归纳和分组,将相似的分在一起。

对称性(Symmetry):”我们倾向于将复杂的视觉信息降低为更为简单的,更有对称性,更容易理解,更有意义的东西。对于同一种信息,我们的大脑视觉区域会对它有很多种可能的解析,但是我们的视觉和感知会选择更加简单和更对称的视觉景象。”

图4: 对称性

我们更倾向于感知为两个菱形,而不是右边的其他的几种形式

闭合性(Closure):“与连续性原理相关的是格式塔封闭性原理:我们的视觉系统自动的尝试将敞开的图形封闭起来,从而将其感知为完整的物体而不是分散的碎片。”

图5:闭合性

受到格式塔原理的启发,利用对称性,闭合性特征,并结合轮廓密度、区域半径等特征,产生最终的显著图。

@2 方法

….待更新

@3 实现

…待更新

@4 实验结果

以数据集中的某一图像为例,展示最终的效果。下图中,将左边四个特征图像利用矩阵回归(或者线性回归)的方法产生右边的显著图。

图6.1:Center-Bias Feature

图6.2 ContourDensity Feature

图6.3: Saliency Map

图6.4: PixelSymmetry Feature

图6.4: Closure&localRadius Feature

@5 源码

Feature.h

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

#pragma once

#include<iostream>

#include<opencv2\opencv.hpp>

#include<opencv2\highgui.hpp>

#include<stdlib.h>

#include<algorithm>

#include<string>

#include<cmath>

#include<vector>

#include<numeric>

class Feature {

public:

cv::Mat srcImg ;

public:

Feature() ;

Feature(cv::Mat) ;

virtual cv::Mat createFeature(cv::Mat&) = 0 ;

virtual cv::Mat createFeature() = 0 ;

virtual void test() = 0;

virtual void test(cv::Mat&)= 0;

//virtual void saveResultMat() = 0;

//virtual void saveResultMat(cv::Mat&) = 0;

};

CenterFeature.h

1

2

3

4

5

6

7

8

9

10

11

12

13

#pragma once

#include"Feature.h"

class CenterFeature: public Feature{

public:

CenterFeature() ;

CenterFeature(cv::Mat& ) ;

cv::Mat createFeature() ;

cv::Mat createFeature(cv::Mat&) ;

void test();

void test(cv::Mat&);

//void saveResultMat();

//void saveResultMat(cv::Mat&);

};

CenterFeature.cpp

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

#include"CenterFeature.h"

using namespace std ;

using namespace cv ;

CenterFeature::CenterFeature() {

cout << "this is the constuctor of CenterFeature..." << endl ;

}

CenterFeature::CenterFeature(Mat& srcImg) {

this->srcImg = srcImg ;

}

void saveResultMat(cv::Mat&) {

 

}

 

void CenterFeature::test() {

this->test(this->srcImg);

}

 

void CenterFeature::test(Mat& srcImg) {

Mat temp;

//string bgrPath = "F:\\MyWorks\\Dataset\\RgbImg\\2018.jpg";

//Mat test = imread(bgrPath, IMREAD_COLOR);

//cvtColor(srcImg, temp, COLOR_BGR2GRAY);

 

/*=======Test the property of the centerB=======*/

srcImg.copyTo(temp);

Feature *cent_Feature = new CenterFeature();

Mat centerB = cent_Feature->createFeature(temp);/* center Bias property */

namedWindow("centerBias", WINDOW_AUTOSIZE);

imshow("centerBias", centerB);

// imwrite("F:\\MyWorks\\test.bmp", 255 * centerB);/* makes centerB [0,255] */

delete cent_Feature;

}

 

Mat CenterFeature::createFeature() {

return this->createFeature(this->srcImg) ;

}

 

Mat CenterFeature::createFeature(Mat& srcImg) {

int centerX_left = 0, centerX_right = 0,

centerY_up = 0, centerY_down = 0;

int h = 0, w = 0 ;/* the h and w of the image */

Size h_w = srcImg.size();

h = h_w.height, w = h_w.width;

if (1 == h % 2) {/* if the h is not % by 2 */

centerX_left = (h + 1) / 2 ;/* get the integer */

centerX_right = (h + 1) / 2 ;

if (1 == w % 2) {

centerY_up = (w + 1) / 2 ;

centerY_down = (w + 1) / 2 ;

}

else

{

resize(srcImg, srcImg, Size(w - 1, h), 0, 0, INTER_NEAREST);/* default inter way is INTER_LINEAR(双线性插值) */

h = srcImg.size().height ;

w = srcImg.size().width ;

centerY_up = (w + 1) / 2 ;

centerY_down = (w + 1) / 2;

}

}else{

resize(srcImg,srcImg,Size(w, h - 1), 0, 0, INTER_NEAREST) ;

h = srcImg.size().height ;

w = srcImg.size().width ;

 

centerX_left = (h + 1) / 2 ;

centerX_right = (h + 1) / 2 ;

if (1 == w % 2) {

centerY_up = (w + 1) / 2 ;

centerY_down = (w + 1) / 2 ;

}else{

cv::resize(srcImg,srcImg,Size(w - 1, h), 0, 0, INTER_NEAREST);

h = srcImg.size().height ;

w = srcImg.size().width ;

centerY_up = (w + 1) / 2 ;

centerY_down = (w + 1) / 2 ;

}

}

Mat weightMat = Mat(h, w, CV_64F,Scalar(0));/* Scalar: makes the each pixel value 0 */

double sigmaX = h / 5, sigmaY = w / 5 ;

double meanX = 0, meanY = 0 ;

double *wMatPtr_i = weightMat.ptr<double>(0);

//cout << h <<endl << w<<endl;

/*=========Create the Gaussian Weight=========*/

int cntw = 0;

int cnth = 0;

auto i = 0, j = 0 ;

for (auto x = -(centerX_left - 1); x <= centerX_right - 1; ++x) {

cnth++;

i = x + centerX_left - 1 ;

//cout << i<<endl;

wMatPtr_i = weightMat.ptr<double>(i) ;

for (auto y = -(centerY_down - 1); y <= centerY_up - 1; ++y) {

cntw++;

j = y + centerY_down - 1 ;

//cout << j<<endl;

wMatPtr_i[j] = (double)(0.5 /( CV_PI * sqrt(sigmaX * sigmaY))) * exp //需要进行强转

(-0.5 * ((pow((x - meanX), 2) / pow(sigmaX, 2)) + (pow((y - meanY), 2) / pow(sigmaY, 2)))) ;

//cout << wMatPtr_i[j] << endl<<endl;

}

}

wMatPtr_i = weightMat.ptr<double>(300);

cout << wMatPtr_i[500];

 

cout << "cnth " << cnth << endl ;

cout << "cntw " << cntw << endl ;

/* ====== Make the size of srcImg be the [768, 516] or [684, 1024] ====== */

if(w > 500 && w < 600){

h = 768 ;

w = 516 ;

}

if(w > 1000){

h = 684 ;

w = 1024 ;

}

cv::resize(weightMat, weightMat, Size(w,h), 0, 0,INTER_LINEAR);

/* the way of inserting the Value: double linear */

 

/*==== nomalization ====*/

double minW = 0, maxW = 0 ;

minMaxLoc(weightMat, &minW, &maxW, NULL, NULL);

/* only need the min and max value of the weightMat,so the other augments are not nessary */

 

cout << maxW << endl;

Mat minValueMat = Mat(h, w, CV_64F, Scalar(minW));

//cout << weightMat.size() << endl;

//cout << minValueMat.size() << endl;

weightMat = (weightMat - minValueMat) / (maxW - minW);//nomalize

minMaxLoc(weightMat, &minW, &maxW, NULL, NULL);

/* only need the min and max value of the weightMat,so the other augments are not nessary */

 

//cout << maxW << " "<< minW<< endl;

/*=== we can also use the cv function nomalize ===*/

return weightMat ;

}

 

 

ContDensityFeature.h

1

2

3

4

5

6

7

8

9

10

11

#include"Feature.h"

class ContDensityFeature : public Feature{

public:

ContDensityFeature() ;

ContDensityFeature(cv::Mat&) ;

cv::Mat createFeature();

cv::Mat createFeature(cv::Mat&);

void test();

void test(cv::Mat&);

//void saveResultMat();

};

 

 

ContDensityFeature.cpp

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

#include"ContDensityFeature.h"

using namespace std ;

using namespace cv ;

ContDensityFeature::ContDensityFeature() {

cout << "this is the default constructor of the ContDensity..." << endl ;

}

ContDensityFeature::ContDensityFeature(Mat& srcImg) {

this->srcImg = srcImg ;

}

 

void ContDensityFeature::test() {

this->test(this->srcImg);

}

void ContDensityFeature::test(cv::Mat& srcImg) {

Feature *cntD_Feature;

Mat temp;

srcImg.copyTo(temp);

cntD_Feature = new ContDensityFeature(temp);

Mat contD = cntD_Feature->createFeature();

namedWindow("contD", WINDOW_AUTOSIZE);

imshow("contD", contD);

delete cntD_Feature;

}

 

Mat ContDensityFeature::createFeature() {

return this->createFeature(this->srcImg) ;

}

Mat ContDensityFeature::createFeature(Mat& srcImg){

srcImg.convertTo(srcImg,CV_64F) ;/* change srcImg to the Double Type */

vector<Mat> channels ;

channels.reserve(srcImg.channels()) ;/* assign the memory space */

split(srcImg, channels);/* save the each channel */

srcImg = channels[0] ;/* only need the first channel */

/*cvtColor(srcImg, srcImg, COLOR_RGB2GRAY) ;*/

// we can also use the cvtColor function to change the format but it must be front of the convertTo function

 

cout << srcImg.rows << " x " << srcImg.cols<<endl ;

 

/*==== initiate the srcImg of the Contour ====*/

double *imPtr = srcImg.ptr<double>(0);

for (auto i = 0; i < srcImg.rows; ++i) {

imPtr = srcImg.ptr<double>(i) ;

for (auto j = 0; j < srcImg.cols; ++j) {

if (0 == imPtr[j])

imPtr[j] = 0.005 ;

}

}

 

/* ==== use the GaussianBlur function to create the contour density map ==== */

double sigma = 40; int N = 40, N_row = 2 * N + 1 ;

GaussianBlur(srcImg, srcImg, Size(N_row, N_row), sigma, sigma, 4);

double minValue = 0, maxValue = 0 ;

minMaxLoc(srcImg, &minValue, &maxValue) ;

srcImg = (srcImg - minValue) / (maxValue - minValue) ;

return srcImg;

}

PixelSymmetryFeature.h

1

2

3

4

5

6

7

8

9

#pragma once

#include"Feature.h"

class PixelSymmetryFeature : public Feature {

public:

PixelSymmetryFeature() ;

PixelSymmetryFeature(cv::Mat&) ;

cv::Mat createFeature();

cv::Mat createFeature(cv::Mat&);

};

PixelSymmetryFeature.cpp

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

#include"PixelSymmetryFeature.h"

using namespace std;

using namespace cv;

PixelSymmetryFeature::PixelSymmetryFeature() {

cout << "this is the default constructor of the PixelSymmetryFeature class..." << endl ;

}

PixelSymmetryFeature::PixelSymmetryFeature(Mat& srcImg) {

this->srcImg = srcImg ;

}

Mat PixelSymmetryFeature::createFeature() {

 

return this->srcImg;

}

 

Mat PixelSymmetryFeature::createFeature(Mat& srcImg) {

auto h = srcImg.rows, w = srcImg.cols ;

if (w > 500 && w < 600) {

h = 768, w = 516 ;

}

if (w > 1000) {

h = 684, w = 1024 ;

}

resize(srcImg, srcImg, Size(w, h), 0, 0, INTER_NEAREST) ;/* the insert value way of nearest */

//.....待完成

return this->srcImg ;

}

LocRegRadiusFeature.h

1

2

3

4

5

6

7

8

9

10

#include"Feature.h"

class LocRegRadiusFeature: public Feature{

public:

LocRegRadiusFeature();

LocRegRadiusFeature(cv::Mat&);

cv::Mat createFeature();

cv::Mat createFeature(cv::Mat&);

void test();

void test(cv::Mat&);

};

}[/cpp]

LocRegRadiusFeature.cpp

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

#include"LocRegRadiusFeature.h"

using namespace std;

using namespace cv;

LocRegRadiusFeature::LocRegRadiusFeature() {

cout << "this is the default constructor of LocRegRadiusFeature class..." << endl;

}

LocRegRadiusFeature::LocRegRadiusFeature(Mat& srcImg) {

this->srcImg = srcImg;

}

 

void LocRegRadiusFeature::test() {

this->test(this->srcImg);

}

 

void LocRegRadiusFeature::test(Mat& srcImg) {

/*=======Test the property of the closure & local region Radius=======*/

Mat temp;

srcImg.copyTo(temp);

LocRegRadiusFeature *lRR_feature = new LocRegRadiusFeature();

Mat LocRegR = lRR_feature->createFeature(temp);

namedWindow("LocRegR", WINDOW_AUTOSIZE);

imshow("LocRegR" ,LocRegR);

delete lRR_feature;

}

 

Mat LocRegRadiusFeature::createFeature() {

return this->createFeature(this->srcImg);

 

}

Mat LocRegRadiusFeature::createFeature(Mat& srcImg) {

//cvtColor(srcImg, srcImg, COLOR_RGB2GRAY);/* Get the single channel img */

srcImg.convertTo(srcImg, CV_64F);

vector<Mat> channels;

channels.reserve(srcImg.channels());/* assign the memory space */

split(srcImg, channels);/* save the each channel */

srcImg = channels[0];/* only need the first channel */

int h = srcImg.rows, w = srcImg.cols;

if (h >500 && w < 600)

h = 768, w = 516;

if (w > 1000)

h = 684, w = 1024;

resize(srcImg, srcImg, Size(w, h), 0, 0, INTER_LINEAR);/* Double LINEAR Way */

 

Mat locRegRadiusMat = Mat(h, w, CV_64F, Scalar(0.0));

double *srcImgPtr = srcImg.ptr<double>(0);

double *l_R_R_M_Ptr = locRegRadiusMat.ptr<double>(0);

for (auto x = 1; x < (h - 1); ++x) {

srcImgPtr = srcImg.ptr<double>(x);

l_R_R_M_Ptr = locRegRadiusMat.ptr<double>(x);

for (auto y = 1; y < w - 1; ++y) {

if (1 == srcImgPtr[y]) {

continue;

}

double sum_dist = 0;

vector<int> oriCloVec(8);/* 8 directions, 1 means closed, 0 is opposite */

 

int flagUP = 1, flagDOWN = 1, flagLEFT = 1, flagRIGHT = 1;

int flagRIGHT_UP = 1, flagLEFT_UP = 1, flagLEFT_DOWN = 1, flagRIGHT_DOWN = 1;

/* scan the 8 directions */

int i = x, j = y + 1;/* anti-clockwise direction */

srcImgPtr = srcImg.ptr<double>(i);

while (flagRIGHT) {

if (0 != srcImgPtr[j]) {

flagRIGHT = 0;

//oriCloVec.insert(oriCloVec.begin(), 1);/* oriCloVec[0] = 1 */

oriCloVec[0] = 1;

}

if(j < w - 1) ++j;

else flagRIGHT = 0;

}

sum_dist = sum_dist + sqrt(pow(x - i, 2) + pow(y - j, 2));

 

i = x - 1; j = y + 1;

srcImgPtr = srcImg.ptr<double>(i);

while (flagRIGHT_UP) {

if (0 != srcImgPtr[j]) {

flagRIGHT_UP = 0;

//oriCloVec.insert(oriCloVec.begin() + 1, 1);/* oriCloVec[1] = 1 */

oriCloVec[1] = 1;

}

if (i > 0 && j < w - 1) { --i, ++j; }

else flagRIGHT_UP = 0;

}

sum_dist = sum_dist + sqrt(pow(x - i, 2) + pow(y - j, 2));

 

i = x - 1; j = y;

srcImgPtr = srcImg.ptr<double>(i);

while (flagUP) {

if (0 != srcImgPtr[j]) {

flagUP = 0;

//oriCloVec.insert(oriCloVec.begin() + 2, 1);/* oriCloVec[2] = 1 *///

oriCloVec[2] = 1;

}

if (i > 0) --i;

else flagUP = 0;

}

sum_dist = sum_dist + sqrt(pow(x - i, 2) + pow(y - j, 2));

 

i = x - 1, j = y - 1;

srcImgPtr = srcImg.ptr<double>(i);

while (flagLEFT_UP) {

if (0 != srcImgPtr[j]) {

flagLEFT_UP = 0;

//oriCloVec.insert(oriCloVec.begin() + 3, 1);/* oriCloVec[3] = 1 */

oriCloVec[3] = 1 ;

}

if (i > 0 && j > 0) { --i, --j; }

else flagLEFT_UP = 0;

}

sum_dist = sum_dist + sqrt(pow(x - i, 2) + pow(y - j, 2));

 

i = x, j = y - 1;

srcImgPtr = srcImg.ptr<double>(i);

while (flagLEFT) {

if (0 != srcImgPtr[j]) {

flagLEFT = 0;

//oriCloVec.insert(oriCloVec.begin() + 4, 1);/* oriCloVec[4] = 1 */

oriCloVec[4] = 1;

}

if (j > 0) --j;

else flagLEFT = 0;

}

sum_dist = sum_dist + sqrt(pow(x - i, 2) + pow(y - j, 2));

 

i = x + 1, j = y - 1;

srcImgPtr = srcImg.ptr<double>(i);

while (flagLEFT_DOWN) {

if (0 != srcImgPtr[j]) {

flagLEFT_DOWN = 0;

//oriCloVec.insert(oriCloVec.begin() + 5, 1);/* oriCloVec[5] = 1 */

oriCloVec[5] = 1;

}

if (i < (h - 1) && j > 0) ++i, --j;

else flagLEFT_DOWN = 0;

}

sum_dist = sum_dist + sqrt(pow(x - i, 2) + pow(y - j, 2));

 

i = x + 1, j = y;

srcImgPtr = srcImg.ptr<double>(i);

while (flagDOWN) {

if (0 != srcImgPtr[j]) {

flagDOWN = 0;

//oriCloVec.insert(oriCloVec.begin() + 6, 1);/* oriCloVec[6] = 1 */

oriCloVec[6] = 1;

}

if (i < (h - 1)) ++i;

else flagDOWN = 0;

}

sum_dist = sum_dist + sqrt(pow(x - i, 2) + pow(y - j, 2));

 

i = x + 1, j = y + 1;

srcImgPtr = srcImg.ptr<double>(i);

while(flagRIGHT_DOWN){

if(0 != srcImgPtr[j]){

flagRIGHT_DOWN = 0;

//oriCloVec.insert(oriCloVec.begin() + 7, 1);/* oriCloVec[7] = 1 */

oriCloVec[7] = 1;

}

if (i < (h - 1) && j < (w - 1)) ++i, ++j;

else flagRIGHT_DOWN = 0;

}

sum_dist = sum_dist + sqrt(pow(x - i, 2) + pow(y - j, 2));

 

double radius_AVG = sum_dist / 8;

 

/*---- calculate the closure weight ----*/

double closureW = exp(std::accumulate(oriCloVec.begin(), oriCloVec.end(), 0) - 8);

/*---- calculate the closure and the local region Radius ----*/

l_R_R_M_Ptr[y] = closureW / (radius_AVG + 150);

 

}

}

 

/*---- Blur ----*/

double sigma = 7; int N = 30; int N_row = 2 * N - 1;

cv::GaussianBlur(locRegRadiusMat, locRegRadiusMat, Size(N_row,N_row), sigma, sigma, 4);

/*---- Norm ----*/

double minValue = 0, maxValue = 0;

cv::minMaxLoc(locRegRadiusMat, &minValue, &maxValue);

cout << minValue << " " << maxValue << endl;

locRegRadiusMat = (locRegRadiusMat - Mat(Size(w,h), CV_64F, Scalar(minValue))) / (maxValue - minValue);

return locRegRadiusMat;

}

Main.cpp

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

#paragma once

#include"Feature.h"

#include"CenterFeature.h"

#include"ContDensityFeature.h"

#include"LocRegRadiusFeature.h"

using namespace cv ;

using namespace std ;

 

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

 

string imPath = "F:\\MyWorks\\Contour2\\2018_2.bmp";

Mat srcImg = imread(imPath, IMREAD_COLOR);/* overload function, the second para is IMREAD_COLOR = 1, which means read the imge by the BRG way */

Feature *feat;

// test center

//feat = new CenterFeature();

//feat->test(srcImg);

/*feat = new ContDensityFeature(srcImg);

feat->test();*/

feat = new LocRegRadiusFeature();

feat->test(srcImg);

 

waitKey(0);

system("pause");

delete feat;

return 0 ;

}