// BaiSeAear.cpp : 定义控制台应用程序的入口点。
//
// 此方法用for循环代替递归的算法,个人感觉很好,因为之前用递归算法,面积大的时候会出现段错误
// 获得二值图是用的opencv函数,可以自己配环境,也可以自己写一个
#include "stdafx.h"
#include "cv.hpp"
typedef struct _info_
{
int saveBlackNum;
int * saveBlack;
}Info;
static Info g_info;
Info * getInfo()
{
return &g_info;
}
int LinkMySelfBlack(unsigned char * destData, int x, int y, int width, int height)
{
Info * t_info = getInfo();
if (x - 1 >= 0 && x - 1 < width && y - 1 >= 0 && y - 1 < height)
{
if (0 == destData[(y - 1) * width + (x - 1)])
{
t_info->saveBlack[t_info->saveBlackNum * 2 + 0] = x - 1;
t_info->saveBlack[t_info->saveBlackNum * 2 + 1] = y - 1;
t_info->saveBlackNum++;
destData[(y - 1) * width + (x - 1)] = 255;
}
}
if (x >= 0 && x < width && y - 1 >= 0 && y - 1 < height)
{
if (0 == destData[(y - 1) * width + (x)])
{
t_info->saveBlack[t_info->saveBlackNum * 2 + 0] = x;
t_info->saveBlack[t_info->saveBlackNum * 2 + 1] = y - 1;
t_info->saveBlackNum++;
destData[(y - 1) * width + x] = 255;
}
}
if (x + 1 >= 0 && x + 1 < width && y - 1 >= 0 && y - 1 < height)
{
if (0 == destData[(y - 1) * width + (x + 1)])
{
t_info->saveBlack[t_info->saveBlackNum * 2 + 0] = x + 1;
t_info->saveBlack[t_info->saveBlackNum * 2 + 1] = y - 1;
t_info->saveBlackNum++;
destData[(y - 1) * width + (x + 1)] = 255;
}
}
if (x - 1 >= 0 && x - 1 < width && y + 1 >= 0 && y + 1 < height)
{
if (0 == destData[(y + 1) * width + (x - 1)])
{
t_info->saveBlack[t_info->saveBlackNum * 2 + 0] = x - 1;
t_info->saveBlack[t_info->saveBlackNum * 2 + 1] = y + 1;
t_info->saveBlackNum++;
destData[(y + 1) * width + (x - 1)] = 255;
}
}
if (x >= 0 && x < width && y + 1 >= 0 && y + 1 < height)
{
if (0 == destData[(y + 1) * width + (x)])
{
t_info->saveBlack[t_info->saveBlackNum * 2 + 0] = x;
t_info->saveBlack[t_info->saveBlackNum * 2 + 1] = y + 1;
t_info->saveBlackNum++;
destData[(y + 1) * width + (x)] = 255;
}
}
if (x + 1 >= 0 && x + 1 < width && y + 1 >= 0 && y + 1 < height)
{
if (0 == destData[(y + 1) * width + (x + 1)])
{
t_info->saveBlack[t_info->saveBlackNum * 2 + 0] = x + 1;
t_info->saveBlack[t_info->saveBlackNum * 2 + 1] = y + 1;
t_info->saveBlackNum++;
destData[(y + 1) * width + (x + 1)] = 255;
}
}
if (x - 1 >= 0 && x - 1 < width && y >= 0 && y < height)
{
if (0 == destData[(y)* width + (x - 1)])
{
t_info->saveBlack[t_info->saveBlackNum * 2 + 0] = x - 1;
t_info->saveBlack[t_info->saveBlackNum * 2 + 1] = y;
t_info->saveBlackNum++;
destData[(y)* width + (x - 1)] = 255;
}
}
if (x + 1 >= 0 && x + 1 < width && y >= 0 && y < height)
{
if (0 == destData[(y)* width + (x + 1)])
{
t_info->saveBlack[t_info->saveBlackNum * 2 + 0] = x + 1;
t_info->saveBlack[t_info->saveBlackNum * 2 + 1] = y;
t_info->saveBlackNum++;
destData[(y)* width + (x + 1)] = 255;
}
}
return 0;
}
int getAear(unsigned char * image, int width, int height)
{
int i = 0;
int j = 0;
int temp = 0;
int tempi = 0;
Info * t_info = getInfo();
t_info->saveBlack = (int *)calloc(sizeof(int), width * height * 2);
int index = 0;
for (j = 0; j < width; j++)
{
for (i = 0; i < height; i++)
{
temp = image[i * width + j];
if (0 == temp)
{
tempi = 0;
t_info->saveBlackNum = 0;
t_info->saveBlack[t_info->saveBlackNum * 2 + 0] = j;
t_info->saveBlack[t_info->saveBlackNum * 2 + 1] = i;
t_info->saveBlackNum++;
image[i * width + j] = 255;
LinkMySelfBlack(image, j, i, width, height);
while (tempi < t_info->saveBlackNum)
{
LinkMySelfBlack(image, t_info->saveBlack[tempi * 2 + 0], t_info->saveBlack[tempi * 2 + 1], width, height);
tempi++;
}
printf("第[%d]个黑色的区域面积 = %d \n", index, t_info->saveBlackNum);
index++;
}
}
}
return 0;
}
int main()
{
cv::Mat image = cv::imread("123.bmp", 0);
cv::Mat dest;
cv::threshold(image, dest, 20, 255, CV_THRESH_BINARY);
cv::imshow("二值图", dest);
getAear(dest.data, dest.cols, dest.rows);
cv::waitKey(0);
return 0;
}
一张二值图,求所有黑色区域的面积
最新推荐文章于 2024-04-27 20:35:00 发布