OpenCV_用积分图像统计像素

在累加多个图像区域的像素时,积分图像显得非常有用。

取图像左上侧的全部像素计算累加和,并用这个累加和替换图像中的每一个像素,用这种方式得到的图像称为积分图像。计算积分图像时只需要对图像扫描一次,这是因为当前积分值等于上一像素的积分值加上当前行的累计值。因此积分图像就是一个包含像素累加和的新图像。

*自适应的阈值化

通过对图像应用阈值来创建二值图像是从图像中提取有意义元素的好方法。

现在我随手拍张书本照片,如下:



当应用单一阈值时 ,结果是这样的:


代码:

int main()
{
	cv::Mat image = cv::imread("book1.jpg");
	cv::cvtColor(image, image, CV_BGR2GRAY);
	cv::imshow("原图",image);
	cv::Mat binaryFixed;
	cv::threshold(image, binaryFixed, 150, 255, cv::THRESH_BINARY);
	cv::imshow("单一阈值结果", binaryFixed);
	cvWaitKey();
}


不管选用什么阈值,图像都会丢失一部分文本,还有部分文本会消失在阴影下,要解决这个问题,有一个办法就是采用局部阈值,即根据每个像素的邻域计算阈值,这种策略称为 自适应阈值化,包括将每个像素的值与邻域的平均值进行比较。如果某像素的值与它的局部平均值差别很大,就会被当作异常值在阈值化过程中剔除。
自适应阈值化需要计算每个像素周围的局部平均值,可通过积分图像提高计算效率。

可以看出,自适应阈值比单一阈值的效果要好得多:



代码:

int main()
{
	cv::Mat image = cv::imread("book1.jpg");
	cv::cvtColor(image, image, CV_BGR2GRAY);
	cv::imshow("原图", image);
	cv::Mat iimage;
	cv::Mat result;
	cv::integral(image, iimage, CV_32S);
	int blockSize = 21;//邻域尺寸
	int threshold = 8;
	int halfSize = blockSize / 2;
	for (int j = halfSize; j < iimage.rows - halfSize - 1; j++)
	{
		uchar* data = image.ptr<uchar>(j);
		int* idata1 = iimage.ptr<int>(j - halfSize);
		int* idata2 = iimage.ptr<int>(j + halfSize + 1);
		for (int i = halfSize; i < iimage.cols - halfSize - 1; i++)
		{
			int sum = (idata2[i + halfSize + 1] - idata2[i - halfSize] - idata1[i + halfSize + 1] + idata1[i - halfSize]) / (blockSize*blockSize);
			if (data[i] < (sum - threshold))
				data[i] = 0;
			else
				data[i] = 255;
		}
	}
	cv::imshow("自适应阈值结果", image);
	cvWaitKey();
}

在OpenCV中也给出了自适应阈值化的函数 cv::adaptiveThreshold()

除了在阈值化中使用局部平均值,还可以使用高斯(Gaussian)加权累计值(ADAPTIVE_THRESH_GAUSSIAN_C标志),这种实现方式比调用cv::adaptiveThreshold快一点

*直方图实现视觉追踪

有一种特殊情况,即由0和1组成的二值图像生成积分图像,这时的积分累计值就是指定区域内值为1 的像素总和。

此处已经研究了一天,代码仍是有误,先mark,回头看(问题出现在IngegralImage模板类的中符号重载函数的at函数)

IntegralImage模板类:

template<typename T, int N>class IntegralImage
{
	cv::Mat integralImage;
public:
	IntegralImage(cv::Mat image)
	{
		cv::integral(image, integralImage, CV_32S);
	}
	cv::Vec<T, N> operator() (int xo, int yo, int width, int height)
	{
		return (integralImage.at<cv::Vec<T, N>>(yo + height, xo + width)
			- integralImage.at<cv::Vec<T, N>>(yo + height, xo)
			- integralImage.at<cv::Vec<T, N>>(yo, xo + width)
			+ integralImage.at<cv::Vec<T, N>>(yo, xo));
	}
};


main函数:

int main()
{
	cv::Mat image = cv::imread("bike.jpg");
	cv::Mat imageROI = image(cv::Rect(350, 76, 100, 100));
	cv::rectangle(image, cv::Rect(350, 76, 100, 100),0);
	cv::imshow("手动识别图", image);
	Histogram1D h;
	h.setNBins(16);
	cv::Mat refHistogram = h.getHistogram(imageROI);
	cv::Mat newImage = cv::imread("bike2.jpg");
	cv::imshow("待检测图像", newImage);
	//首先创建16个平面的二值图像
	cv::Mat planes;
	convertToBinaryPlanes(newImage, planes, 16);
	//然后计算积分图像
	IntegralImage<float, 16> intHistogram(planes);
	double maxSimilarity = 0.0;
	int xbest = 0, ybest = 0;
	double distance = 0;
	cv::Mat histogram;
	for (int y = 0; y < newImage.rows; y++)
	{
		for (int x = 0; x < newImage.cols - 100; x++)
		{
			histogram = intHistogram(x, y, 100, 100);
			distance = cv::compareHist(refHistogram, histogram, CV_COMP_INTERSECT);
			if (distance > maxSimilarity)
			{
				xbest = x;
				ybest = y;
				maxSimilarity = distance;
			}
		}
	}
	cv::rectangle(newImage, cv::Rect(xbest, ybest, 100, 100), 0);
	cv::imshow("检测图像", newImage);
	cvWaitKey();

}



  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
第1章导论.................................................................................................................................. 1 1.0.1 为什么要处理图像?.........................................................................................1 1.0.2 什么是一幅图像?.............................................................................................1 1.0.3 什么是一幅数字图像?.....................................................................................1 1.0.4 什么是一个光谱带?.........................................................................................1 1.0.5 为什么大多数图像处理算法都参照灰度图像进行,而实际中遇到的都是彩色图像?.....................................................................................2 1.0.6 一幅数字图像是如何形成的?.........................................................................2 1.0.7 如果一个传感器对应物理世界中的一个小片,如何能让多个传感器对应场景中的同一个小片?.................................................................2 1.0.8 什么是图像中一个像素位置亮度的物理含义?............................................3 1.0.9 为什么图像常用512×512,256×256,128×128 等来表示?........................4 1.0.10 需要多少个比特以存储一幅图像?...............................................................5 1.0.11 什么决定了一幅图像的质量?.......................................................................5 1.0.12 什么会使得图像模糊?...................................................................................5 1.0.13 图像分辨率是什么含义?...............................................................................5 1.0.14 “良好对比度”是什么含义?.........................................................................7 1.0.15 图像处理的目的是什么?...............................................................................8 1.0.16 如何进行图像处理?.......................................................................................8 1.0.17 图像处理中使用非线性操作符吗?...............................................................9 1.0.18 什么是线性操作符?.......................................................................................9 1.0.19 如何来定义线性操作符?.......................................................................

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值