要点
1.边界线链码
2.链码的长度,区域面积
3.计算灰度共生矩阵,特征
4.SIFT特征
解释
1.边界线链码
简单来说就是利用一个八邻域去搜索图像的边界,这里自然指的是二值图像。
利用点的八邻域信息,选择下一个点作为边界点,这个算法需要选择一个开始点,可以选择图像上是目标点,在最上,最左的点。然后查看它的八邻域的点,从右下方45°的位置开始寻找,如果是目标点,将沿顺时针90°作为下一次寻找的方向,如果不是,则逆时针45°继续寻找,一旦找到重复上面的过程。
参考:CSDN
2.灰度共生矩阵
我自己还是不写了,大家看参考。
参考:CSDN
3.SIFT特征
原理网上一搜一大把。。
参考:CSDN
程序
1.边界线链码
#include <cv.h>
#include <highgui.h>
#include <iostream>
#include <stack>
using namespace std;
int main()
{
IplImage * image, *image2, *image3;
image = cvLoadImage("F:\\c_code\\week8_1\\week8_1\\1.png", 0);
cvNamedWindow("image", 1);
cvShowImage("image", image);
image2 = cvCreateImage(cvSize(image->width, image->height), image->depth, 1);
image3 = cvCreateImage(cvSize(image->width, image->height), image->depth, 1);
cvZero(image2);//image2 赋值为0
cvZero(image3);
//寻找区域的左上角点
CvPoint startPoint = cvPoint(0, 0);
bool bFindStartpoint = false;
int i, j;
unsigned char * ptr, *dst;
stack<int> board;//奇数位存储x坐标,偶数位存储y坐标
//当前扫描点
CvPoint currentPoint = cvPoint(0, 0);
//邻域的8个点的方向
int directions[8][2] = { { 0, 1 }, { 1, 1 }, { 1, 0 }, { 1, -1 }, { 0, -1 }, { -1, -1 }, { -1, 0 }, { -1, 1 } };
int beginDirection = 0;
bool bFindBoardpoint = false;//寻找到邻域的边界点的判定
for (i = 0; i< image->height && bFindStartpoint == false; i++)
{
for (j = 0; j< image->width && bFindStartpoint == false; j++)
{
ptr = (unsigned char *)(image->imageData + i*image->widthStep + j);
if (*ptr == 255)
{
startPoint.x = j;
startPoint.y = i;
bFindStartpoint = true;
cout<<"x: " << j <<" y : " <<i <<endl;
cvWaitKey(0);
}
}
}
//进行边界跟踪 每次搜索8个方向的点 找到了即停止
currentPoint = startPoint;
bFindStartpoint = false;
beginDirection = 0;
board.push(startPoint.x);
board.push(startPoint.y);
while (!bFindStartpoint)
{
bFindBoardpoint = false;
//在8个方向寻找符合条件的边界点
while (!bFindBoardpoint)
{
//进行出界判定
ptr = (unsigned char *)(image->imageData + (currentPoint.y + directions[beginDirection][1])* image->widthStep + currentPoint.x + directions[beginDirection][0]);
if (*ptr == 255)
{
bFindBoardpoint = true;
currentPoint.x += directions[beginDirection][0];
currentPoint.y += directions[beginDirection][1];
/************************************************************************/
/* 此处添加序列存储的代码 */
/************************************************************************/
//一、将边界存储到图片中
dst = (unsigned char *)image2->imageData + currentPoint.y * image2->widthStep + currentPoint.x;
*dst = 255;
//二、将边界点的序列存储到一个堆栈中
board.push(currentPoint.x);
board.push(currentPoint.y);
if (currentPoint.x == startPoint.x && currentPoint.y == startPoint.y)
{
bFindStartpoint = true;
}
//改变下次首先开始扫描的方向
beginDirection -= 2;
if (beginDirection < 0)
{
beginDirection += 8;
}
}
else
{
beginDirection++;
beginDirection = beginDirection % 8;
}
}
cout<<"currentPoint "<<currentPoint.x <<" "<< currentPoint.y<<endl;
}
cvNamedWindow("image2", 1);
cvShowImage("image2", image2);
int lianmaLength = (board.size() + 5) / 10;