OpenCV统计米粒数目-计算联通区域的个数及联通区域内像素的个数
#include <stdio.h>
#include <math.h>
#include <time.h>
#include <c6x.h>
#include <stdlib.h>
#include <string.h>
#include "reader.h"
#include "grey2color.h"
#include "rgb2yuv.h"
/*
* 仅限使用24位bmp格式图片
* 656--512
* */
/*******************************************************algrithem***********************************************************/
void IMG_thr_8_cn
(
const unsigned char *grey,
const unsigned char *BackGround,
unsigned char *restrict thresholdArray,
short cols,
short rows,
unsigned char threshold
)
{
int i;
int pixels = rows * cols;
#ifndef NOASSUME
_nassert((int)grey % 8 == 0);
_nassert((int)grey % 8 == 0);
_nassert((int)thresholdArray % 8 == 0);
_nassert(pixels % 16 == 0);
_nassert(pixels >= 16);
#endif
int temp = 0;
for(i=0;i < pixels;i++)
{
temp = abs(grey[i] - BackGround[i]);
thresholdArray[i] = temp > threshold ? 255 : 0;
}
}
/****
* 图像缩放
* (宽高只支持4的倍数)
* *****/
void imageSmall(unsigned char *restrict inputImage,
unsigned char * outputImage,
const int width,
const int height)
{
_nassert(width > 0);
_nassert(height > 0);
_nassert((int)width % 4 == 0);
_nassert((int)height % 4 == 0);
int i,j;
int temp = 0;
int i_out = 0;
int j_out = 0;
// int h_index = height >> 2;
int w_index = width >> 2;
for (j = 0; j < height; j+=4)
{
for (i = 0; i < width; i+=4)
{
temp = *(inputImage + width*j + i);
i_out = i >> 2;
j_out = j >> 2;
*(outputImage + w_index*j_out + i_out) = temp;
}
}
}
void imageBig(unsigned char *restrict inputImage,
unsigned char * outputImage,
const int width,
const int height)
{
_nassert(width > 0);
_nassert(height > 0);
_nassert((int)width % 4 == 0);
_nassert((int)height % 4 == 0);
int i,j;
int temp = 0;
int i_out = 0;
int j_out = 0;
int w_index = width >> 2;
for (j = 0; j < height; j++)
{
for (i = 0; i < width; i++)
{
i_out = i >> 2;
j_out = j >> 2;
temp = *(inputImage + w_index*j_out + i_out);
*(outputImage + width*j + i) = temp;
}
}
}
void areaCount(int *restrict labelmap, int *restrict area, const int width, const int height, const int labelIndex)
{
_nassert(width > 0);
_nassert(height > 0);
_nassert((int)width % 4 == 0);
_nassert((int)height % 4 == 0);
int i,cx,cy,index = 0;
int realWidth = width - 1;
int realHeight = height - 1;
#pragma MUST_ITERATE(120,,) //C函数循环优化
for(cy = 1; cy < realHeight; cy++) //统计各个连通域的面积
{
#pragma MUST_ITERATE(160,,) //C函数循环优化
for(cx = 1; cx < realWidth; cx++)
{
index = cy * width + cx;
for(i = 1; i < labelIndex + 1; i++)
{
area[i] = labelmap[index] == i ? area[i] + 1 : area[i];
}
}
}
}
typedef struct QNode{
int data;
struct QNode *next;
}QNode;
typedef struct Queue{
struct QNode* first;
struct QNode* last;
}Queue;
void PushQueue(Queue *queue, int data){
QNode *p = NULL;
p = (QNode*)malloc(sizeof(QNode));
p->data = data;
if(queue->first == NULL){
queue->first = p;
queue->last = p;
p->next = NULL;
}
else{
p->next = NULL;
queue->last->next = p;
queue->last = p;
}
}
int PopQueue(Queue *queue){
QNode *p = NULL;
int data;
if(queue->first == NULL){
return -1;
}
p = queue->first;
data = p->data;
if(queue->first->next == NULL){
queue->first = NULL;
queue->last = NULL;
}
else{
queue->first = p->next;
}
free(p);
return data;
}
static int NeighborDirection[8][2] = {{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},{-1,1}};
void SearchNeighbor(unsigned char *bitmap, int width, int height, int *labelmap,
int labelIndex, int pixelIndex, Queue *queue){
int searchIndex, i, length;
labelmap[pixelIndex] = labelIndex;
length = width * height;
for(i = 0;i < 8;i++)
{
searchIndex = pixelIndex + NeighborDirection[i][0] * width + NeighborDirection[i][1];
if(searchIndex > 0 && searchIndex < length &&
bitmap[searchIndex] == 255 && labelmap[searchIndex] == 0)
{
labelmap[searchIndex] = labelIndex;
PushQueue(queue, searchIndex);
}
}
}
int ConnectedComponentLabeling(unsigned char *bitmap, unsigned char *out, int width, int height, int *ConnectedComponentArea, int *labelmap)
{
int i;
int cx, cy, index, popIndex, labelIndex = 0;
Queue *queue = NULL;
queue = (Queue*)malloc(sizeof(Queue));
queue->first = NULL;
queue->last = NULL;
memset(labelmap, 0, width * height);
for(cy = 1; cy < height - 1; cy++){
for(cx = 1; cx < width - 1; cx++){
index = cy * width + cx;
if(bitmap[index] == 255 && labelmap[index] == 0){
labelIndex++;
SearchNeighbor(bitmap, width, height, labelmap, labelIndex, index, queue);
popIndex = PopQueue(queue);
while(popIndex > -1){
SearchNeighbor(bitmap, width, height, labelmap, labelIndex, popIndex, queue);
popIndex = PopQueue(queue);
}
}
}
}
free(queue); //5 221 565 【0303 1 012 986】
/******************************************/
int area[400]; //定义连通域面积,最多允许400个连通域
for(i = 0; i < 400 ; i++)area[i] = 0;
/*
int realWidth = width - 1;
int realHeight = height - 1;
int temp;
for(cy = 1; cy < realHeight; cy++) //统计各个连通域的面积
{
for(cx = 1; cx < realWidth; cx++)
{
index = cy * width + cx;
for(i = 1; i < labelIndex + 1; i+=2)
{
if(labelmap[index] == i) //1 042 908
{
area[i]++;
}
}
// for(i = 1; i < labelIndex + 1; i+=2) //978 528
// {
// if(labelmap[index] == i)
// {
// area[i]++;
// }
// if(labelmap[index] == i + 1)
// {
// area[i + 1]++;
// }
// }
}
}
*/
areaCount(labelmap, area, width, height, labelIndex); //【0303 687 390】
int label[10] = {0}; //允许存留连通域个数,最多9个,label[0]不用
int piclabel = 1; //标签个数
for(i = 1; i < labelIndex + 1; i++)
{
printf("area[%d] = %d \n", i, area[i]);
if(area[i] < 2500 && area[i] > 80)
{
label[piclabel] = i; //只保存面积符合要求的连通区域的标签
printf("gas label[%d] = %d \n", piclabel, label[piclabel]);
piclabel++;
}
}
printf("main piclabel num = %d \n", piclabel - 1);
int num = 0;
for(cy = 1; cy < height - 1; cy++)
{
for(cx = 1; cx < width - 1; cx++)
{
index = cy * width + cx;
for(i=1; i < piclabel ; i++)
{
if(labelmap[index] == label[i])
{
out[index] = 255;
num++;
}
}
}
}
*ConnectedComponentArea = num;
return labelIndex; //52 090 225 【0303 563 112】
}
/*************************************************************************/
int main(void)
{
int i, j;
int width;
int height;
int row,col;
unsigned char *picdata01 = (unsigned char*)0x90000000;
unsigned char *picdata02 = (unsigned char*)0x90100000;
unsigned short *bitwidth = (unsigned short *)(picdata01 + 0x00000012);
unsigned short *bitheight = (unsigned short *)(picdata01 + 0x00000016);
height = *bitheight;
width = *bitwidth;
row = height;
col = width;
unsigned char *r1 = (unsigned char *)malloc(width*height*sizeof(unsigned char));
unsigned char *g1 = (unsigned char *)malloc(width*height*sizeof(unsigned char));
unsigned char *b1 = (unsigned char *)malloc(width*height*sizeof(unsigned char));
unsigned char *r2 = (unsigned char *)malloc(width*height*sizeof(unsigned char));
unsigned char *g2 = (unsigned char *)malloc(width*height*sizeof(unsigned char));
unsigned char *b2 = (unsigned char *)malloc(width*height*sizeof(unsigned char));
reader(picdata01, r1, g1, b1, width, height);
reader(picdata02, r2, g2, b2, width, height);
/**********************获取背景帧和后续数据帧*************************/
unsigned char *grey = (unsigned char *)malloc(width*height*sizeof(unsigned char));
unsigned char *BackGround = (unsigned char *)malloc(width*height*sizeof(unsigned char));
unsigned char* outpic = (unsigned char*)malloc(row*col*sizeof(unsigned char));
int temp = 0;
for(i=0;i < row;i++)
{
for(j=0;j<col;j++)
{
temp = (b1[i*col + j] + g1[i*col + j] + r1[i*col + j])/3;
BackGround[i*col + j] = temp;
}
}
for(i=0;i < row;i++)
{
for(j=0;j<col;j++)
{
temp = (b2[i*col + j] + g2[i*col + j] + r2[i*col + j])/3;
grey[i*col + j] = temp;
}
}
/**********************获取背景帧和后续数据帧*************************/
int threshold = 10; //一般情况下取10
int ConCompLabNum = 0;
unsigned char* difference = (unsigned char*)malloc(row*col*sizeof(unsigned char)); //3 774 824
unsigned char* thresholdArray = (unsigned char*)malloc(row*col*sizeof(unsigned char));
unsigned char *outb = outpic;
unsigned char *outg = outb + row*col;
unsigned char *outr = outg + row*col;
IMG_thr_8_cn(grey, BackGround, thresholdArray, col, row, threshold); //671 773
unsigned char* smallThArr = (unsigned char*)malloc(row/4*col/4*sizeof(unsigned char));
unsigned char* smallOut = (unsigned char*)malloc(row/4*col/4*sizeof(unsigned char));
int* labelpic = (int*)malloc(row/4*col/4*sizeof(int));
imageSmall(thresholdArray, smallThArr, width, height); //[0303 43 808]
int area;
ConCompLabNum = ConnectedComponentLabeling(smallThArr, smallOut, width/4, height/4, &area, labelpic); //[0303 2 270 238]
printf("ConnectedComponentLabeling = %d \n",ConCompLabNum);
unsigned char* out = (unsigned char*)malloc(row*col*sizeof(unsigned char));
imageBig(smallOut, out, width, height); //[0303 344 609]
int* colorCoordX = (int*)malloc(area*16*sizeof(int));
int* colorCoordY = (int*)malloc(area*16*sizeof(int));
int index = 0;
for(i=0;i < row;i++) //[0303 1 869 132]
{
for(j=0;j<col;j++)
{
if(out[i*col + j] > 0)
{
outb[i*col + j] = ToRed(grey[i*col + j] * 5);
outg[i*col + j] = ToGreen(grey[i*col + j] * 5);
outr[i*col + j] = ToBlue(grey[i*col + j] * 5);
// outb[i*col + j] = 255;
// outg[i*col + j] = 255;
// outr[i*col + j] = 255;
colorCoordX[index] = j; // 1 886 971
colorCoordY[index] = i;
index++;
}
else
{
outb[i*col + j] = grey[i*col + j];
outg[i*col + j] = grey[i*col + j];
outr[i*col + j] = grey[i*col + j];
// outb[i*col + j] = 0;
// outg[i*col + j] = 0;
// outr[i*col + j] = 0;
}
}
}
unsigned char *pYUV = (unsigned char *)malloc(row*col*2*sizeof(unsigned char));
// BGR24ToYUV420_Packed(outpic, pYUV, colorCoordX, colorCoordY, 4*area, width, height); //5 299 962
// 218 470
BGR24ToYUV422_Packed(outpic, pYUV, colorCoordX, colorCoordY, 16*area, width, height);
free(difference);
free(thresholdArray);
free(labelpic);
free(smallThArr);
free(smallOut);
free(out);
free(colorCoordX);
free(colorCoordY);
free(pYUV);
/***********************输出************************/
free(b1);
free(g1);
free(r1);
free(b2);
free(g2);
free(r2);
free(grey);
free(BackGround);
free(outpic);
return 0;
}
/*
* main.c
*/
#include <stdio.h>
#include <math.h>
#include <time.h>
#include <c6x.h>
#include <stdlib.h>
#include <string.h>
#include "reader.h"
#include "grey2color.h"
/*
* 仅限使用24位bmp格式图片
* 656--512
* */
/*******************************************************algrithem***********************************************************/
typedef struct Node_Int //链表的整型节点,其中定两个data点,是为了解决pair的特性
{
int data1;
int data2;
struct Node_Int * pNext;
} NODE, *PNODE;
//整型栈
typedef struct Stack_Int {
PNODE pTop;
PNODE pBottom;
int size; //栈的大小
} STACK_INT, *PSTACK;
/************初始化栈*************/
void StackInit(PSTACK pStack)
{
pStack->pTop = (PNODE)malloc(sizeof(NODE));
if (NULL == pStack->pTop)
{
printf("内存分配失败");
}
else
{
pStack->pBottom = pStack->pTop;
pStack->pTop->pNext = NULL;
pStack->size = 0;
}
}
//压栈
void StackPush(PSTACK pStack, int val1, int val2)
{
PNODE pNew = (PNODE)malloc(sizeof(NODE));//每次压栈前,先分配一个节点的内存
pNew->data1 = val1;
pNew->data2 = val2;
pNew->pNext = pStack->pTop;
pStack->pTop = pNew;
pStack->size++;
}
//是否为空栈
int StackIsEmpty(PSTACK pS)//是否为空栈
{
if (pS->pTop == pS->pBottom)
{
return 1;
}
else
return 0;
}
//出栈
int StackPop(PSTACK pS, int *pVal1, int *pVal2)//把pS所指向的栈出栈一次
{
if (StackIsEmpty(pS))
{
return 0;
}
else
{
PNODE r = pS->pTop;
*pVal1 = r->data1;
*pVal2 = r->data2;
pS->pTop = r->pNext;
free(r);
r = NULL;
pS->size--;
return 1;
}
}
//遍历
void StackTraverse(PSTACK pStack)//遍历栈中元素
{
PNODE pNew = pStack->pTop;
while (pNew != pStack->pBottom)
{
printf("%d,%d \n", pNew->data1, pNew->data2);
pNew = pNew->pNext;
}
printf("\n");
}
//清空栈
void StackClear(PSTACK pS)//释放栈空间
{
if (StackIsEmpty(pS))
{
return;
}
else
{
PNODE pT = pS->pTop;
PNODE q = NULL;
while (pT != pS->pBottom)
{
printf("stack free \n");
q = pT->pNext;
free(pT);
pT = q;
}
pS->pTop = pS->pBottom;
pS->size = 0;
}
}
int GetDiffImage(unsigned char *inputImg1, //输入:第一幅图
unsigned char *inputImg2, //输入:第二幅图
unsigned char *diffImg, //输出:差分图
int width, int height)
{
int i;
if(inputImg1 == NULL || inputImg2 == NULL || diffImg == NULL)
{
printf("输入的图像数为空!!\n");
return 0;
}
int temp = 0;
for (i = 0; i < width * height; i++)
{
temp = abs(*(inputImg2 + i) - *(inputImg1 + i));
*(diffImg + i) = temp;
}
return 1;
}
//将图像二值化
int ImageToThresholdImage(unsigned char *srcImg, //输入:源图
unsigned char *outImg, //输出:输出图
int width, int height,
int threshold) //输出:域值
{
if(srcImg == NULL || outImg == NULL)
{
printf("输入的图像数为空!!\n");
return 0;
}
int i, j;
for (j = 0; j < height; j++)
{
for (i = 0; i < width; i++)
{
if (*(srcImg + width*j + i) > threshold)
{
*(outImg + width*j + i) = 1;
// printf("outImg[%d] = %d \n",width*j + i, outImg[width*j + i]);
}
else
{
*(outImg + width*j + i) = 0;
}
}
}
return 1;
}
//数组的存储顺序为maxX,maxY,minX,minY
void stackToArray(STACK_INT inputPoints, int * outputPoints)
{
int i;
//确保空间足够
if (inputPoints.size>2000)
{
printf("输出数组空间不够!\n");
return;
}
int count = 2 * inputPoints.size;
//translate
int stackPopVal1, stackPopVal2;
for (i = 0; i < count; i+=2)
{
StackPop(&inputPoints, &stackPopVal1, &stackPopVal2);
*(outputPoints + i) = stackPopVal1;
*(outputPoints + i + 1) = stackPopVal2;
}
}
void seekCoordinate(unsigned char * image, PSTACK inputPoints, int width, int height)
{
int maxX, minX, maxY, minY;
//由于C中变量不能在下文声明再使用,故在此先声明.2017年1月19日 add by WJ
int curPixel[2];
int stackPopVal1, stackPopVal2; //用于接收出栈的数据
//使用带整型节点的数据 替代 C++标准模版中的整型栈 edit by WJ 2017年1月19日
// STACK_INT points;
// StackInit(&points);//先初始化一个栈,试分配一下内存,安全起见
int label = 1; // start by 2
int i, j;
for (j = 1; j < height - 1; j++)
{
for (i = 1; i < width - 1; i++)
{
int data = *(image + j*width + i);
if (data == 1) //前景像素
{
minX = i;
maxX = minX;
minY = j;
maxY = minY;
// STACK_INT neighborPixels;
// StackInit(&neighborPixels);
PSTACK neighborPixels;
neighborPixels = (PSTACK)malloc(sizeof(STACK_INT));
StackPush(neighborPixels, j, i); //将坐标入栈
++label; // 记录第几个前景像素
/*************************
* 查找每个连通域的极大坐标点和极小坐标点
* ****************************/
while (!StackIsEmpty(neighborPixels))
{
// get the top pixel on the stack and label it with the same label
int curX, curY;
/**curPixel数组已在前方声明,替代pair edit by WJ**/
curPixel[0] = (*neighborPixels).pTop->data1;
curPixel[1] = (*neighborPixels).pTop->data2;
curY = curPixel[0];
curX = curPixel[1];
//有问题,需要修改
*(image + curY*width + curX) = label; //将连通区域的像素设置为标记号
// printf("image = %d label = %d (%d,%d)\n",image[curY*width+curX], label, curY, curX);
//更新边界点,永远取最大边界
if (maxX < curX) maxX = curX;
if (minX > curX) minX = curX;
if (maxY < curY) maxY = curY;
if (minY > curY) minY = curY;
// pop the top pixel 像素出栈
StackPop(neighborPixels, &stackPopVal1, &stackPopVal2);
// push the 4-neighbors (foreground pixels) 将4领域的前景像素入栈
if (curX - 1 >= 0 && curX - 1 < width && curY >= 0 && curY < height) // left pixel
{
if (*(image + curY*width + curX - 1) == 1)
{
StackPush(neighborPixels, curY, curX - 1);
}
}
if (curX + 1 >= 0 && curX + 1 < width && curY >= 0 && curY < height) // right pixel
{
if (*(image + curY*width + curX + 1) == 1)
{
StackPush(neighborPixels, curY, curX + 1);
}
}
if (curX >= 0 && curX < width && curY - 1 >= 0 && curY - 1 < height) // right pixel
{
if (*(image + (curY - 1)*width + curX) == 1)
{
StackPush(neighborPixels, curY - 1, curX);
}
}
if (curX >= 0 && curX < width && curY + 1 >= 0 && curY + 1 < height) // down pixel
{
if (*(image + (curY + 1)*width + curX) == 1)
{
StackPush(neighborPixels, curY + 1, curX);
}
}
}
//存入所有的区域坐标
StackPush(inputPoints, maxX, maxY);//极大点坐标
// printf("maxX = %d, maxY = %d \n", maxX, maxY);
StackPush(inputPoints, minX, minY);//极小点坐标
// printf("minX = %d, minY = %d \n", minX, minY);
free(neighborPixels);
}
}
}
// printf("points.size:%d\n", points.size);//edit by WJ//std::cout << points.size() << std::endl;
// *inputPoints = points;
// printf("StackTraverse(points) \n");
// StackTraverse(&points);
printf("StackTraverse(inputPoints) \n");
StackTraverse(inputPoints);
// StackClear(&points); //释放栈空间
// printf("StackTraverse(points) \n");
// StackTraverse(&points);
}
void imagePyrDown(unsigned char * inputImage, unsigned char * outputImage)
{
int height = 512, width = 656;
int i,j;
int temp = 0;
for (j = 0; j < height; j++)
{
if (j % 4 == 0)
{
for (i = 0; i < width; i++)
{
if (i % 4 == 0)
{
temp = *(inputImage + width*j + i);
*(outputImage + (width/4)*(j / 4) + i / 4) = temp;
}
else
{
continue;
}
}
}
else
{
continue;
}
}
}
void calculateCoordinate(STACK_INT inputPoints ,PSTACK outPoints)
{
// STACK_INT outputPoints;
//定义xy变量
int maxXI, minXI, maxYI, minYI;
int maxXO, minXO, maxYO, minYO;
int stackPopVal1, stackPopVal2;
int times = 4;
int i = 0;
// StackInit(&outputPoints);//先初始化一个栈,试分配一下内存,安全起见
int count = inputPoints.size / 2; //一个方向上的坐标技数
for (i = 0; i < count; i++)
{
StackPop(&inputPoints, &stackPopVal1, &stackPopVal2);
maxXI = stackPopVal1;
maxYI = stackPopVal2;
StackPop(&inputPoints, &stackPopVal1, &stackPopVal2);
minXI = stackPopVal1;
minYI = stackPopVal2;
printf("in:\n");
printf("%d,%d\n", maxXI, maxYI);
printf("%d,%d\n", minXI, minYI);
//考虑循环越界问题,根据当前坐标,推算原始的边界问题
if (minXI * times - 1 < 0)
minXO = 0;
else
minXO = minXI * times - 1;
if (minYI * times - 1<0)
minYO = 0;
else
minYO = minYI * times - 1;
if (maxXI * times + 1>654) //640--638 656--654
maxXO = 654;
else
maxXO = maxXI * times + 1;
if (maxYI * times + 1>510) //480--478 512--510
maxYO = 510;
else
maxYO = maxYI * times + 1;
printf("out:\n");
printf("%d,%d\n", maxXO, maxYO);
printf("%d,%d\n", minXO, minYO);
//小区域面积大于某个设定阈值时保存区域坐标
if ((maxXO - minXO + 1)*(maxYO - minYO + 1) > 20)
{
//顺序存储 先(maxXO, maxYO) 后(minXO, minYO)
StackPush(outPoints, maxXO, maxYO);
StackPush(outPoints, minXO, minYO);
}
}
// *outPoints = outputPoints;
printf("StackTraverse(outPoints) \n");
StackTraverse(outPoints);
// printf("StackTraverse(outputPoints) \n");
// StackTraverse(&outputPoints);
// StackClear(&outputPoints); //释放栈空间
// printf("StackTraverse(outPoints) \n");
// StackTraverse(outPoints);
// printf("StackTraverse(outputPoints) \n");
// StackTraverse(&outputPoints);
}
void fastFeaturePointsAndTrack(unsigned char* inputImage,
int * inputCoordinate,
int * outputCoordinate,
int fastThreshold,
int width,
int height,
int *a1,
double *a2
)
{
int cycleTime, tempCycleTime = 0;
int i, j, k;
//std::stack<std::pair<int, int>> keyPoints;
STACK_INT keyPoints;
StackInit(&keyPoints);//先初始化一个栈,试分配一下内存,安全起见
int inputCoordinateSize = 0;
for (i = 0; i < 2000; i++)
{
if (inputCoordinate[i] != -1)
{
inputCoordinateSize++;
}
else
{
break;
}
}
cycleTime = inputCoordinateSize / 4;
//cycleTime = 1;//test
// printf("cycleTime:%d\n", cycleTime);
int currentArea;
//Points_Per_Pixel
double ppp;
//遍历单个单个区域的特征
while (tempCycleTime < cycleTime){
//取区域坐标
int maxX, minX, maxY, minY;
//数组的存储顺序为maxX,maxY,minX,minY
maxX = inputCoordinate[tempCycleTime * 4 + 0];
maxY = inputCoordinate[tempCycleTime * 4 + 1];
minX = inputCoordinate[tempCycleTime * 4 + 2];
minY = inputCoordinate[tempCycleTime * 4 + 3];
//判断坐标点是否存在访问越界
if (minX<3)
{
minX = 3;
}
if (maxX>height)
{
maxX = height - 3;
}
if (minY<3)
{
minY = 3;
}
if (maxY>width)
{
maxY = width - 3;
}
//计算区域面积
currentArea = (maxX - minX + 1)*(maxY - minY + 1);
*a1 = currentArea;
printf("currentArea:%d \n", currentArea); //.........................................................
int xxx = 0;
for (j = minY; j < maxY; j++)
{
for (i = minX; i < maxX; i++)
{
int pc = *(inputImage + j*width + i);
/*
0:中心点灰度值+TH < 周围点灰度值
1:中心点灰度值 > 周围点灰度值+TH
2:其他
*/
int check[16], checkFlag[3];
for (k = 0; k < 16; k++)
{
// int pt;
if (k == 0){
/*pt = inputImage.at<uchar>(j - 3, i);*/
int pt = *(inputImage + (j-3)*width + i);
if (pc + fastThreshold < pt){
check[0] = 0;
}
else if (pc>pt + fastThreshold){
check[0] = 1;
}
else{
check[0] = 2;
}
}
if (k == 1){
/*pt = inputImage.at<uchar>(j - 3, i + 1);*/
int pt = *(inputImage + (j-3)*width + i+1);
if (pc + fastThreshold < pt){
check[1] = 0;
}
else if (pc>pt + fastThreshold){
check[k] = 1;
}
else{
check[k] = 2;
}
}
if (k == 2){
/*pt = inputImage.at<uchar>(j - 2, i + 2);*/
int pt = *(inputImage + (j-2)*width + i+2);
if (pc + fastThreshold < pt){
check[k] = 0;
}
else if (pc>pt + fastThreshold){
check[k] = 1;
}
else{
check[k] = 2;
}
}
if (k == 3){
/*pt = inputImage.at<uchar>(j - 1, i + 3);*/
int pt = *(inputImage + (j - 1)*width + i + 3);
if (pc + fastThreshold < pt){
check[k] = 0;
}
else if (pc>pt + fastThreshold){
check[k] = 1;
}
else{
check[k] = 2;
}
}
if (k == 4){
/*pt = inputImage.at<uchar>(j, i + 3);*/
int pt = *(inputImage + j*width + i + 3);
if (pc + fastThreshold < pt){
check[k] = 0;
}
else if (pc>pt + fastThreshold){
check[k] = 1;
}
else{
check[k] = 2;
}
}
if (k == 5){
/*pt = inputImage.at<uchar>(j + 1, i + 3);*/
int pt = *(inputImage + (j + 1)*width + i + 3);
if (pc + fastThreshold < pt){
check[k] = 0;
}
else if (pc>pt + fastThreshold){
check[k] = 1;
}
else{
check[k] = 2;
}
}
if (k == 6){
/*pt = inputImage.at<uchar>(j + 2, i + 2);*/
int pt = *(inputImage + (j + 2)*width + i + 2);
if (pc + fastThreshold < pt){
check[k] = 0;
}
else if (pc>pt + fastThreshold){
check[k] = 1;
}
else{
check[k] = 2;
}
}
if (k == 7){
/*pt = inputImage.at<uchar>(j + 3, i + 1);*/
int pt = *(inputImage + (j + 3)*width + i + 1);
if (pc + fastThreshold < pt){
check[k] = 0;
}
else if (pc>pt + fastThreshold){
check[k] = 1;
}
else{
check[k] = 2;
}
}
if (k == 8){
/*pt = inputImage.at<uchar>(j + 3, i);*/
int pt = *(inputImage + (j + 3)*width + i );
if (pc + fastThreshold < pt){
check[k] = 0;
}
else if (pc>pt + fastThreshold){
check[k] = 1;
}
else{
check[k] = 2;
}
}
if (k == 9){
/*pt = inputImage.at<uchar>(j + 3, i - 1);*/
int pt = *(inputImage + (j + 3)*width + i -1);
if (pc + fastThreshold < pt){
check[k] = 0;
}
else if (pc>pt + fastThreshold){
check[k] = 1;
}
else{
check[k] = 2;
}
}
if (k == 10){
/*pt = inputImage.at<uchar>(j + 2, i - 2);*/
int pt = *(inputImage + (j + 2)*width + i - 2);
if (pc + fastThreshold < pt){
check[k] = 0;
}
else if (pc>pt + fastThreshold){
check[k] = 1;
}
else{
check[k] = 2;
}
}
if (k == 11){
/*pt = inputImage.at<uchar>(j + 1, i - 3);*/
int pt = *(inputImage + (j + 1)*width + i - 3);
if (pc + fastThreshold < pt){
check[k] = 0;
}
else if (pc>pt + fastThreshold){
check[k] = 1;
}
else{
check[k] = 2;
}
}
if (k == 12){
/*pt = inputImage.at<uchar>(j, i - 3);*/
int pt = *(inputImage + j*width + i - 3);
if (pc + fastThreshold < pt){
check[k] = 0;
}
else if (pc>pt + fastThreshold){
check[k] = 1;
}
else{
check[k] = 2;
}
}
if (k == 13){
/*pt = inputImage.at<uchar>(j - 1, i - 3);*/
int pt = *(inputImage + (j - 1)*width + i - 3);
if (pc + fastThreshold < pt){
check[k] = 0;
}
else if (pc>pt + fastThreshold){
check[k] = 1;
}
else{
check[k] = 2;
}
}
if (k == 14){
/*pt = inputImage.at<uchar>(j - 2, i - 2);*/
int pt = *(inputImage + (j - 2)*width + i - 2);
if (pc + fastThreshold < pt){
check[k] = 0;
}
else if (pc>pt + fastThreshold){
check[k] = 1;
}
else{
check[k] = 2;
}
}
if (k == 15){
/*pt = inputImage.at<uchar>(j - 3, i - 1);*/
int pt = *(inputImage + (j - 3)*width + i - 1);
if (pc + fastThreshold < pt){
check[k] = 0;
}
else if (pc>pt + fastThreshold){
check[k] = 1;
}
else{
check[k] = 2;
}
}
/*
0:中心点灰度值+TH < 周围点灰度值
1:中心点灰度值 > 周围点灰度值+TH
2:其他
寻找8连续点
*/
checkFlag[0] = 0; checkFlag[1] = 0;
for (k = 0; k < 25; k++)
{
if (k < 16){
if (check[k] == 0){
checkFlag[1] = 0;
checkFlag[0] = checkFlag[0] + 1;
}
else if (check[k] == 1){
checkFlag[0] = 0;
checkFlag[1] = checkFlag[1] + 1;
}
else{
checkFlag[0] = 0; checkFlag[1] = 0;
}
}
else{
if (check[k - 16] == 0){
checkFlag[1] = 0;
checkFlag[0] = checkFlag[0] + 1;
}
else if (check[k - 16] == 1){
checkFlag[0] = 0;
checkFlag[1] = checkFlag[1] + 1;
}
}
//判断明暗连续点是否有8个
if (checkFlag[0] == 8)
{
/*keyPoints.push(std::pair<int, int>(i, j));*/
StackPush(&keyPoints, i, j);
xxx++;
break;
}
}
}
}
}
// printf("xxx = %d \n",xxx);
// ppp = ((double)keyPoints.size) / currentArea;
ppp = keyPoints.size / (currentArea*1.0);
*a2 = ppp;
printf("ppp:%f \n", ppp); //.......................................................
int temp_outputCoordinate = 0;
if (ppp < 0.1)
{
//数组的存储顺序为maxX,maxY,minX,minY
outputCoordinate[temp_outputCoordinate++] = maxX;
outputCoordinate[temp_outputCoordinate++] = maxY;
outputCoordinate[temp_outputCoordinate++] = minX;
outputCoordinate[temp_outputCoordinate++] = minY;
}
//标记出特征点
while (StackIsEmpty(&keyPoints) == 0)
{
int curX, curY;
curX = keyPoints.pTop->data1;
curY = keyPoints.pTop->data2;
int stackPopVal1, stackPopVal2;//用于接收出栈的数据
*(inputImage + curY*width + curX) = 255;
StackPop(&keyPoints, &stackPopVal1, &stackPopVal2);
}
StackClear(&keyPoints);
tempCycleTime++;
}
}
/*************************************************************************/
int main(void)
{
int i, j, k;
int width;
int height;
int row,col;
unsigned char *picdata01 = (unsigned char*)0x90000000;
unsigned char *picdata02 = (unsigned char*)0x90100000;
unsigned short *bitwidth = (unsigned short *)(picdata01 + 0x00000012);
unsigned short *bitheight = (unsigned short *)(picdata01 + 0x00000016);
height = *bitheight;
width = *bitwidth;
row = height;
col = width;
unsigned char *r1 = (unsigned char *)malloc(width*height*sizeof(unsigned char));
unsigned char *g1 = (unsigned char *)malloc(width*height*sizeof(unsigned char));
unsigned char *b1 = (unsigned char *)malloc(width*height*sizeof(unsigned char));
unsigned char *r2 = (unsigned char *)malloc(width*height*sizeof(unsigned char));
unsigned char *g2 = (unsigned char *)malloc(width*height*sizeof(unsigned char));
unsigned char *b2 = (unsigned char *)malloc(width*height*sizeof(unsigned char));
reader(picdata01, r1, g1, b1, width, height);
reader(picdata02, r2, g2, b2, width, height);
/**********************获取背景帧和后续数据帧*************************/
unsigned char *grey = (unsigned char *)malloc(width*height*sizeof(unsigned char));
unsigned char *BackGround = (unsigned char *)malloc(width*height*sizeof(unsigned char));
unsigned char *outpic = (unsigned char *)malloc(3*width*height*sizeof(unsigned char));
int temp = 0;
for(i=0;i < row;i++)
{
for(j=0;j<col;j++)
{
temp = (b1[i*col + j] + g1[i*col + j] + r1[i*col + j])/3;
BackGround[i*col + j] = temp;
}
}
for(i=0;i < row;i++)
{
for(j=0;j<col;j++)
{
temp = (b2[i*col + j] + g2[i*col + j] + r2[i*col + j])/3;
grey[i*col + j] = temp;
}
}
/**********************获取背景帧和后续数据帧*************************/
unsigned char *diffImage = (unsigned char *)malloc(width*height*sizeof(unsigned char));
unsigned char *pThreshold = (unsigned char*)malloc(sizeof(unsigned char)*width*height);
unsigned char *pThresholdPyrDown = (unsigned char*)malloc(sizeof(unsigned char)*width*height / 16);
unsigned char *pOutput = (unsigned char*)malloc(sizeof(unsigned char)*width*height * 3);
// int oriPoints[2000], trackCoordinate[2000];
int *oriPoints = (int *)malloc(2000*sizeof(int));
int *trackCoordinate = (int *)malloc(2000*sizeof(int));
int threshold = 20;
PSTACK points = NULL;
PSTACK backPoints = NULL;
points = (PSTACK)malloc(sizeof(STACK_INT));
backPoints = (PSTACK)malloc(sizeof(STACK_INT));
GetDiffImage(BackGround, grey, diffImage, width, height); //获得差分图像
ImageToThresholdImage(diffImage, pThreshold, width, height, threshold); //将获得差分图像二值化
imagePyrDown(pThreshold, pThresholdPyrDown); //将图像缩小
seekCoordinate(pThresholdPyrDown, points, width/4, height/4);
StackTraverse(points);
calculateCoordinate(*points, backPoints);
memset(oriPoints, -1, 2000);
memset(trackCoordinate, -1, 2000);
stackToArray(*backPoints, oriPoints);
// StackClear(points);
// StackClear(backPoints);
free(points);
free(backPoints);
// StackTraverse(points);
// StackTraverse(backPoints);
int currentArea;
double ppp;
fastFeaturePointsAndTrack(diffImage, oriPoints, trackCoordinate, 10, width, height, ¤tArea, &ppp);
printf("currentArea = %d, ppp = %f \n",currentArea, ppp);
/*************************************************************/
int count = 0;
for (i = 0; i < 2000; i++)
{
if (*(trackCoordinate + i) != -1)
count++;
else
break;
}
//先全图赋值
for (j = 0; j < height; j++)
{
for (i = 0; i < width; i++)
{
pOutput[width*j + i] = 0;
// *(grey + width*j + i);
pOutput[width*height + width*j + i] = 0;
// *(grey + width*j + i);
pOutput[2*width*height + width*j + i] = 0;
// *(grey + width*j + i);
}
}
for (k = 0; k < count / 4; k++)
{
//取区域坐标
int maxX, minX, maxY, minY;
maxX = trackCoordinate[k * 4 + 0];
maxY = trackCoordinate[k * 4 + 1];
minX = trackCoordinate[k * 4 + 2];
minY = trackCoordinate[k * 4 + 3];
for (j = minY; j < maxY; j++)
{
for (i = minX; i < maxX; i++)
{
if (*(diffImage + width*j + i) > 10)
{
pOutput[width*j + i] = ToBlue(diffImage[width*j + i]) * 5;
pOutput[width*height + width*j + i] = ToGreen(diffImage[width*j + i]) * 5;
pOutput[2*width*height + width*j + i] = ToRed(diffImage[width*j + i]) * 5;
}
}
}
}
/***********************输出************************/
unsigned char *outb = (unsigned char *)malloc(3*width*height*sizeof(unsigned char));
unsigned char *outg = outb + row*col;
unsigned char *outr = outg + row*col;
unsigned char*p01 = NULL;
unsigned char*p02 = NULL;
unsigned char*p03 = NULL;
p01 = pOutput; //b
p02 = p01 + width*height; //g
p03 = p02 + width*height; //r
for(i=0;i<height;i++)
{
for(j=0; j<width; j++)
{
outb[i*col + j] = p01[i*col + j];
outg[i*col + j] = p02[i*col + j];
outr[i*col + j] = p03[i*col + j];
}
}
free(b1);
free(g1);
free(r1);
free(b2);
free(g2);
free(r2);
free(grey);
free(BackGround);
free(outpic);
free(oriPoints);
free(trackCoordinate);
free(diffImage);
free(pThreshold);
free(pThresholdPyrDown);
free(pOutput);
return 0;
}