把遇到的问题挨个记下来吧 ,都是比较弱智的问题。
1:Mat result1(5, 5, CV_8UC1, Scalar(255));
这句话 是创建一个5*5的矩阵,数据类型为CV_8UC1 意思为无符号字符型 C1代表通道数是1 Scalar(255)代表给矩阵元素赋值为255,result1(5, 5, CV_8UC2, Scalar(255,0));两个通道,第一个通道赋值为255 第二个通道赋值为0.
2.:MorphoFeatures() :threShold(-1), cross(5, 5, CV_8U, Scalar(0))
其中MorphoFeatures是定义好的一个类名 这样使用应该是构造函数,构造函数一般用来初始化变量。但是构造函数后面加一个:还有后面的那些东西不太了解了就。下面附上答案:
单冒号(:)的作用:
public:和private:后面的冒号,表示后面定义的所有成员都是公有或私有的,直到下一个public: 或 private: 出现为止。private: 为默认处理。
构造函数后面的冒号起分隔作用,是类给成员变量赋值的方法,更适合const类成员变量,比如下面:
class fun
{
public: int a;
Mat image;
fun() :a(5), image(5, 5, CV_8SC1, Scalar(128))
{
cout << a << endl;
cout << image << endl;
}
};
3:Mat_<uchar>::const_iterator it = binary.begin<uchar>();
这句话 应该是声明一个图像的迭代器 ,有两种方式,这种方式是使用的定义在Mat_内部的迭代器类型。另一种方式就是:
cv::Mat Iterator _<Vec3b> it //声明一个图像的迭代器
const_iterator:表明 it是一个指向常量的指针,注意!这里是指向常量的指针,比如程序中写*it =4;编译器会告诉这是非法的,因为it指向的是一个常量,是不允许修改的。 但是it值可变。
4:变量定义的问题 在定义二值化阈值变量的时候 定义为:int threShold注意 这里的threShold中的S是大写的 一般变量或者函数定义的时候牵扯到两个单词的时候第一个单词小写第二个单词开头字母大写,请注意二值化的函数threshold()这个函数名字中的字母都是小写,阈值变量如果定义成小写就会成问题!!细节注意一下就好。C++区分大小写。
5:位深度的概念:
示例:8位颜色的图,位深度就是8,用2的8次幂表示,它含有256种颜色 ( 或256种灰度等级 )。4位颜色可称之为真彩色,位深度是24,它能组合成2的24次幂种颜色,即:16777216种颜色,当我们用24位来记录颜色时,实际上是以2^(8×3),即红、绿、蓝 ( RGB ) 三基色各以2的8次幂,256种颜色而存在的,三色组合就形成一千六百万种颜色。
6:二值化函数threshold()函数的二值化操作只针对单通道图像,可以是8位uchar 或者32位的float。
7:定义角点检测中用到的结构元素 分别 十字形 菱形 方形 x形 关键我根本不知道为什么要定义这些东西啊 ,这些东西有什么用???在图像处理中他们是怎么工作的呢?为什么用这些掩码就可以得到图像的角特征呢??为什么要先十字形膨胀 在菱形腐蚀呢???
附上代码:
#include<opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
class MorphoFeatures
{
private:
//设定二值化的阈值
int threShold;
//定义角点检测中用到的结构元素 分别 十字形 菱形 方形 x形
Mat cross;
Mat diamond;
Mat square;
Mat x;
public:
MorphoFeatures() :
threShold(-1), cross(5, 5, CV_8U, Scalar(0)), diamond(5, 5, CV_8U, Scalar(0)), square(5, 5, CV_8U, Scalar(1)),x(5,5,CV_8U,Scalar(0))
{
for (int i = 0; i < 5; i++)
{
cross.at<uchar>(2, i) = 1;
cross.at<uchar>(i, 2) = 1;
}
diamond.at<uchar>(0, 2) = 1;
diamond.at<uchar>(1, 1) = 1;
diamond.at<uchar>(1, 3) = 1;
diamond.at<uchar>(2, 0) = 1;
diamond.at<uchar>(2, 4) = 1;
diamond.at<uchar>(3, 1) = 1;
diamond.at<uchar>(3, 3) = 1;
diamond.at<uchar>(4, 2) = 1;
for (int i = 0; i < 5; i++)
{
x.at<uchar>(i, i) = 1;
x.at<uchar >(4 - i, i) = 1;
}
}
/*二值化阈值设定函数*/
void setThreshold(int t)
{
threShold = t;
}
/*图像二值化函数*/
void applyThreshold(Mat & result)
{
if (threShold > 0)
{
threshold(result, result, threShold, 255, THRESH_BINARY);//二值化 函数
}
}
Mat getCorners(const Mat &image)
{
Mat result;
//十字膨胀
dilate(image, result, cross);
//菱形腐蚀
erode(result, result, diamond);
Mat result2;
//X形 膨胀
dilate(image, result2, x);
//方形腐蚀
erode(result2, result2, square);
//做差得到角点图像
absdiff(result2, result, result);
//二值化图像 使之看起来比较清晰
applyThreshold(result);
return result;
}
/*边界 获取 函数*/
Mat getEdges(const Mat &image)
{
Mat result;
morphologyEx(image, result, MORPH_GRADIENT, Mat());
applyThreshold(result);
return result;
}
/*给角点画一个圆圈 */
void drawOnImage(const Mat &binary, Mat &image)
{
Mat_<uchar>:: const_iterator it = binary.begin<uchar>();
Mat_<uchar>::const_iterator itEnd = binary.end<uchar>();
for (int i = 0; it != itEnd; i++, it++)
{
if (*it)
{
circle(image, Point(i%image.step, i / image.step), 5, Scalar(255, 0, 0));
}
}
}
};
int main()
{
MorphoFeatures morphology;
morphology.setThreshold(40);
Mat image = imread("Test.jpg",IMREAD_GRAYSCALE);
Mat edges,corners;
edges = morphology.getEdges(image);
imshow("边缘图像", edges);
corners = morphology.getCorners(image);
imshow("角点图像", corners);
//corners是经过二值化的图像 使用这个图像的是为了定位图像边角所在的位置,以便于在image上标注出来。
morphology.drawOnImage(corners, image);
imshow("角点画圆", image);
waitKey(0);
return 0;
}