版权声明:转载记得声明~~~ :) https://blog.csdn.net/ReCclay/article/details/82812913
普通写法
代码
#include "cv.h"
#include "highgui.h"
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "stdlib.h"
#define CAMERA_H 120 //图片高度
#define CAMERA_W 188 //图片宽度
#define white 255 //255对应图像白色
#define black 0 //0对应图像黑色
typedef unsigned char uint8; //uint8 是单片机程序常用的8位数据类型
uint8 img[CAMERA_H][CAMERA_W] = { 0 }; //图像所在的数组!!!!!!
IplImage* pImg_1 = NULL; //原图图像指针
IplImage* pImg_2 = NULL; //当前图图像指针
char pos[1000]; //保存路径的字符数组
void CoverCarhead(void);
void ExtractZone(void);
int main()
{
/*以下为读取图像,并将图像灰度信息保存在img数组里(不需要理解)*/
pImg_1 = cvCreateImage(cvSize(CAMERA_W, CAMERA_H), 8, 3);
cvNamedWindow("原图", 0);//创建窗口
sprintf(pos, "%d.jpg", 6);///////////////////请在此处修改路径!!!如路径为“C:\\桌面\\fiscar\\2.jpg”,修改函数为:sprintf(pos, "C:\\桌面\\fiscar\\%d.jpg", 2);
//图片如果在工程文件夹中不需要标注路径
pImg_1 = cvLoadImage(pos, 0);
cvShowImage("原图", pImg_1);
CvScalar s;
int i, j;
for (i = 0; i<CAMERA_H; i++)
{
for (j = 0; j<CAMERA_W; j++)
{
s = cvGet2D(pImg_1, i, j);
img[i][j] = s.val[0];
if (img[i][j] > 100) img[i][j] = 255;
else img[i][j] = 0;
}
}
/*以上为读取图像,并将图像灰度信息保存在img数组里(不需要理解)*/
/*以下为你的代码,提取出的连通域部分请用灰色表示(将灰度值改为100)*/
CoverCarhead(); //盖住车头
ExtractZone(); //提取联通域
/*以上为你的代码,提取出的连通域部分请用灰色表示(将灰度值改为100)*/
/*以下为显示修改后的图像(不需要理解),按空格结束程序*/
pImg_2 = cvCreateImage(cvSize(CAMERA_W, CAMERA_H), 8, 3);
cvNamedWindow("当前图", 0);//创建窗口
for (i = 0; i<CAMERA_H; i++)
{
for (j = 0; j<CAMERA_W; j++)
{
s = cvGet2D(pImg_2, i, j);
s.val[0] = img[i][j];
s.val[1] = img[i][j];
s.val[2] = img[i][j];
cvSet2D(pImg_2, i, j, s);
}
}
cvShowImage("当前图", pImg_2);
cvWaitKey(0); //等待按键
/*以上为显示修改后的图像(不需要理解),按空格结束程序*/
}
void example(void)
{
int line, col; //这是一段演示代码,在图像上画了一个灰黑色十字
for (line = 50; line <= 60; line++) //这是一段演示代码,在图像上画了一个灰黑色十字
img[line][94] = 0; //这是一段演示代码,在图像上画了一个灰黑色十字
for (line = 60; line <= 70; line++) //这是一段演示代码,在图像上画了一个灰黑色十字
img[line][94] = 10; //这是一段演示代码,在图像上画了一个灰黑色十字
for (col = 84; col <= 94; col++) //这是一段演示代码,在图像上画了一个灰黑色十字
img[60][col] = 127; //这是一段演示代码,在图像上画了一个灰黑色十字
for (col = 94; col <= 104; col++) //这是一段演示代码,在图像上画了一个灰黑色十字
img[60][col] = 200; //这是一段演示代码,在图像上画了一个灰黑色十字
}
void CoverCarhead(void)
{
int i, j;
for(i=75; i<120; i++)
{
for(j=70; j<112; j++)
{
img[i][j] = 255;
}
}
}
void ExtractZone(void)
{
int i, j;
int BorderLeft[120], BorderRight[120], Middle[120];
int LGetFlag[120], RGetFlag[120];
for(i=CAMERA_H-1; i>=0; i--)
{
BorderLeft[i] = 0;
BorderRight[i] = 0;
Middle[i] = 94;
LGetFlag[i] = 0;
RGetFlag[i] = 0;
}
for(i=CAMERA_H-1; i>=0; i--)
{
if(i == CAMERA_H-1)
{
//往左
for(j=94; j>=2; j--)
{
if(img[i][j]==white && LGetFlag[i]==0)
{
img[i][j] = 100;
if(img[i][j-1]==black && img[i][j-2]==black)
{
BorderLeft[i] = j-1;
LGetFlag[i] = 1;
}
else
{
BorderLeft[i] = 2;
}
}
}
//往右
for(j=95; j<=CAMERA_W-3; j++)
{
if(img[i][j]==white && RGetFlag[i]==0)
{
img[i][j] = 100;
if(img[i][j+1]==black && img[i][j+2]==black)
{
BorderRight[i] = j+1;
RGetFlag[i] = 1;
}
else
{
BorderRight[i] = CAMERA_W-3;
}
}
}
Middle[i] = (BorderRight[i] + BorderLeft[i]) / 2;
}
else
{
for(j=Middle[i+1]; j>=2; j--)
{
if(img[i][j]==white && LGetFlag[i]==0)
{
img[i][j] = 100;
if(img[i][j-1]==black && img[i][j-2]==black)
{
BorderLeft[i] = j-1;
LGetFlag[i] = 1;
}
else
{
BorderLeft[i] = 2;
}
}
}
for(j=Middle[i+1]+1; j<=CAMERA_W-3; j++)
{
if(img[i][j]==white && RGetFlag[i]==0)
{
img[i][j] = 100;
if(img[i][j+1]==black && img[i][j+2]==black)
{
BorderRight[i] = j+1;
RGetFlag[i] = 1;
}
else
{
BorderRight[i] = CAMERA_W-3;
}
}
}
Middle[i] = (BorderRight[i] + BorderLeft[i]) / 2;
}
}
}
效果展示
上面自己写的这个逐行扫的方式,显然对于3 5 6 7都是不适应的。
然后就有了大神的,连通域写法
,但是目前写出的这个连通域运行效率低,还待改进!
连通域写法
代码
#include "cv.h"
#include "highgui.h"
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "stdlib.h"
#define CAMERA_H 120 //图片高度
#define CAMERA_W 188 //图片宽度
#define white 255 //255对应图像白色
#define black 0 //0对应图像黑色
typedef unsigned char uint8; //uint8 是单片机程序常用的8位数据类型
uint8 img[CAMERA_H][CAMERA_W] = { 0 }; //图像所在的数组!!!!!!
uint8 new_img[CAMERA_H][CAMERA_W] = { 0 };
IplImage* pImg_1 = NULL; //原图图像指针
IplImage* pImg_2 = NULL; //当前图图像指针
char pos[1000]; //保存路径的字符数组
void CoverCarhead(void);
void ExtractZone(void);
struct link
{
int x;
int y;
struct link *new_up;
struct link *new_down;
struct link *new_left;
struct link *new_right;
};
void example1(struct link *start_point);
int main()
{
/*以下为读取图像,并将图像灰度信息保存在img数组里(不需要理解)*/
pImg_1 = cvCreateImage(cvSize(CAMERA_W, CAMERA_H), 8, 3);
cvNamedWindow("原图", 0);//创建窗口
sprintf(pos, "%d.jpg", 6);///////////////////请在此处修改路径!!!如路径为“C:\\桌面\\fiscar\\2.jpg”,修改函数为:sprintf(pos, "C:\\桌面\\fiscar\\%d.jpg", 2);
//图片如果在工程文件夹中不需要标注路径
pImg_1 = cvLoadImage(pos, 0);
cvShowImage("原图", pImg_1);
CvScalar s;
int i, j;
for (i = 0; i<CAMERA_H; i++)
{
for (j = 0; j<CAMERA_W; j++)
{
s = cvGet2D(pImg_1, i, j);
img[i][j] = s.val[0];
new_img[i][j] = 0;//新数组初始化
if (img[i][j] > 100) img[i][j] = 255;
else img[i][j] = 0;
}
}
/*以上为读取图像,并将图像灰度信息保存在img数组里(不需要理解)*/
for (i = 74;i < 120;i++)
{
for (j = 70;j < 118;j++)
{
img[i][j] = 255;
}
}
for (i = 0; i<CAMERA_H; i++)
{
for (j = 0; j<CAMERA_W; j++)
{
s.val[0] = img[i][j];
s.val[1] = img[i][j];
s.val[2] = img[i][j];
cvSet2D(pImg_1, i, j, s);
}
}
cvShowImage("原图", pImg_1);
/*以下为你的代码,提取出的连通域部分请用灰色表示(将灰度值改为100)*/
// CoverCarhead(); //盖住车头
// ExtractZone(); //提取联通域
struct link *ptr = NULL;
ptr = (struct link *)malloc(sizeof(struct link));
ptr->x = 115;
ptr->y = 94;
ptr->new_down = NULL;
ptr->new_up = NULL;
ptr->new_left = NULL;
ptr->new_right = NULL;
printf("%d,%d\n",ptr->x,ptr->y);
example1(ptr);//////////演示代码,编程时请注释
/*以上为你的代码,提取出的连通域部分请用灰色表示(将灰度值改为100)*/
/*以下为显示修改后的图像(不需要理解),按空格结束程序*/
pImg_2 = cvCreateImage(cvSize(CAMERA_W, CAMERA_H), 8, 3);
cvNamedWindow("当前图", 0);//创建窗口
for (i = 0; i<CAMERA_H; i++)
{
for (j = 0; j<CAMERA_W; j++)
{
// s = cvGet2D(pImg_2, i, j);
// s.val[0] = img[i][j];
// s.val[1] = img[i][j];
// s.val[2] = img[i][j];
// cvSet2D(pImg_2, i, j, s);
if (new_img[i][j] == 1)
{
s.val[0] = 100;
s.val[1] = 100;
s.val[2] = 100;
printf("YSE/n");
}
else
{
s.val[0] = 0;
s.val[1] = 0;
s.val[2] = 0;
}
cvSet2D(pImg_2, i, j, s);
}
}
cvShowImage("当前图", pImg_2);
cvWaitKey(0); //等待按键
/*以上为显示修改后的图像(不需要理解),按空格结束程序*/
}
void example(void)
{
int line, col; //这是一段演示代码,在图像上画了一个灰黑色十字
for (line = 50; line <= 60; line++) //这是一段演示代码,在图像上画了一个灰黑色十字
img[line][94] = 0; //这是一段演示代码,在图像上画了一个灰黑色十字
for (line = 60; line <= 70; line++) //这是一段演示代码,在图像上画了一个灰黑色十字
img[line][94] = 10; //这是一段演示代码,在图像上画了一个灰黑色十字
for (col = 84; col <= 94; col++) //这是一段演示代码,在图像上画了一个灰黑色十字
img[60][col] = 127; //这是一段演示代码,在图像上画了一个灰黑色十字
for (col = 94; col <= 104; col++) //这是一段演示代码,在图像上画了一个灰黑色十字
img[60][col] = 200; //这是一段演示代码,在图像上画了一个灰黑色十字
}
void CoverCarhead(void)
{
int i, j;
for(i=75; i<120; i++)
{
for(j=70; j<112; j++)
{
img[i][j] = 255;
}
}
}
void ExtractZone(void)
{
int i, j;
int BorderLeft[120], BorderRight[120], Middle[120];
int LGetFlag[120], RGetFlag[120];
for(i=CAMERA_H-1; i>=0; i--)
{
BorderLeft[i] = 0;
BorderRight[i] = 0;
Middle[i] = 94;
LGetFlag[i] = 0;
RGetFlag[i] = 0;
}
for(i=CAMERA_H-1; i>=0; i--)
{
if(i == CAMERA_H-1)
{
//往左
for(j=94; j>=2; j--)
{
if(img[i][j]==white && LGetFlag[i]==0)
{
img[i][j] = 100;
if(img[i][j-1]==black && img[i][j-2]==black)
{
BorderLeft[i] = j-1;
LGetFlag[i] = 1;
}
else
{
BorderLeft[i] = 2;
}
}
}
//往右
for(j=95; j<=CAMERA_W-3; j++)
{
if(img[i][j]==white && RGetFlag[i]==0)
{
img[i][j] = 100;
if(img[i][j+1]==black && img[i][j+2]==black)
{
BorderRight[i] = j+1;
RGetFlag[i] = 1;
}
else
{
BorderRight[i] = CAMERA_W-3;
}
}
}
Middle[i] = (BorderRight[i] + BorderLeft[i]) / 2;
}
else
{
for(j=Middle[i+1]; j>=2; j--)
{
if(img[i][j]==white && LGetFlag[i]==0)
{
img[i][j] = 100;
if(img[i][j-1]==black && img[i][j-2]==black)
{
BorderLeft[i] = j-1;
LGetFlag[i] = 1;
}
else
{
BorderLeft[i] = 2;
}
}
}
for(j=Middle[i+1]+1; j<=CAMERA_W-3; j++)
{
if(img[i][j]==white && RGetFlag[i]==0)
{
img[i][j] = 100;
if(img[i][j+1]==black && img[i][j+2]==black)
{
BorderRight[i] = j+1;
RGetFlag[i] = 1;
}
else
{
BorderRight[i] = CAMERA_W-3;
}
}
}
Middle[i] = (BorderRight[i] + BorderLeft[i]) / 2;
}
}
}
void example1(struct link *start_point)
{
int i,j;
static int ttt = 0;
printf("%d,%d\n",start_point->x,start_point->y);
if (start_point->x < 119&&start_point->x >=1&&start_point->y < 187&&start_point->y >=1)
{
ttt++;
if (new_img[start_point->x][start_point->y] == 1)
{
return;
}
if (img[start_point->x][start_point->y] == 255)
{
new_img[start_point->x][start_point->y] = 1;
start_point->new_down = (struct link *)malloc(sizeof(struct link));
start_point->new_up = (struct link *)malloc(sizeof(struct link));
start_point->new_left = (struct link *)malloc(sizeof(struct link));
start_point->new_right = (struct link *)malloc(sizeof(struct link));
start_point->new_down->x = start_point->x + 1;
start_point->new_down->y = start_point->y;
start_point->new_down->new_down = NULL;
start_point->new_down->new_up = NULL;
start_point->new_down->new_left = NULL;
start_point->new_down->new_right = NULL;
start_point->new_up->x = start_point->x - 1;
start_point->new_up->y = start_point->y;
start_point->new_up->new_down = NULL;
start_point->new_up->new_up = NULL;
start_point->new_up->new_left = NULL;
start_point->new_up->new_right = NULL;
start_point->new_left->x = start_point->x;
start_point->new_left->y = start_point->y + 1;
start_point->new_left->new_down = NULL;
start_point->new_left->new_up = NULL;
start_point->new_left->new_left = NULL;
start_point->new_left->new_right = NULL;
start_point->new_right->x = start_point->x;
start_point->new_right->y = start_point->y - 1;
start_point->new_right->new_down = NULL;
start_point->new_right->new_up = NULL;
start_point->new_right->new_left = NULL;
start_point->new_right->new_right = NULL;
//printf("%d,%d\n",start_point->new_down->x,start_point->new_down->y);
printf("%d,%d\n",start_point->new_up->x,start_point->new_up->y);
//printf("%d,%d\n",start_point->new_right->x,start_point->new_right->y);
printf("%d,%d\n",start_point->new_left->x,start_point->new_left->y);
example1(start_point->new_down);
example1(start_point->new_up);
example1(start_point->new_left);
example1(start_point->new_right);
}
else
{
return;
}
}
else
return;
}