提取图像直方图(图像处理)

继直方图规定化后的研究

由于直方图规定化是根据两张图片的累计直方图进行图像的处理。对于这个处理过程,我尝试了很图像进行替换色系,但是没有找到一个相对合适案例,来体现直方图规定化这个算法的精妙之处。在多次尝试中,我发现一个灰度图像(原图)和一个彩色图像(规定化图)进行直方图规定化处理后,就会得到一个彩色的图像。

我的发现

我们都知道,灰度图像转换为彩色图形,一般情况下都是假彩色。如何将一个灰度图像进行还原成原本的彩色图像,那就是我们需要获得彩色图像的直方图。

创新之处

我利用彩色图像,生成一个色条,该色条与宽度无关。也就是说,我用 1 个像素宽,n 个像素长的有颜色的色条,就可以储存该图像的直方图。通过该色条与一张灰度图像,使用直方图规定化算法就可以将彩色图像还原出来。

具体的用处

  1. 一种新的图像储存方式,使得图像的存储空间更小。
  2. 作为直方图规定化的后续研究提供另一种思路。
  3. 解决一些需要由灰度图像转换为彩色图像的便
...

直方图规定化(图像处理)

直方图规定化说明

简单说明一下直方图,就是对图像的像素值的个数进行统计,然后分别计算出每一种像素值所占所有像素数量(图像大小)的比例。累计直方图就是将统计起来算好的比例依次累加。举个例子,当像素值为 1 时它所占得比例所对应的累计比例就是它本身。而像素值为 2 时它的累计比例就是像素值为 1 时的比例加上像素值为 2 时的比例。依次类推,像素值为 255 时,所对应的累计比例为 1。

直方图规定化的操作就是计算两张图片的累计直方图,然后进行对应的计算,将一个图片的色系替换给另一个图片。(个人理解,仅供参考)

处理图片介绍

这里我选用了一张小王子的图片作为需要处理的图片,一张不同颜色比例分布的图片。将不同颜色比例的照片的色系替换掉小王子的色系,生成一张新色系的图片。如果感兴趣,还可以尝试其他图片,不同的图片效果不同。

图片显示


图1 原图


...

图像旋转(图像处理)

图像旋转说明

虽然在 EasyX 中有专门的图像旋转的函数,但是这个函数只是实现了图像旋转的这个功能。其中具体的旋转实现过程就像是个黑匣子一样,而且该函数旋转之后的图像显示不够完整。针对以上问题,我使用双线性内插法,实现了一个比较完整的图像旋转算法。

我对图像旋转的理解

图像旋转是宏观,而旋转的过程是微观的。我们看到的是一个图像整体的旋转,实现整体旋转的过程是每一个像素值位置的移动。

关于移动的方式,分为直接法和间接法。直接法是由原图像的像素位置去计算旋转后图像的位置,间接法是有旋转后图像的位置去反算原图的位置从而获得像素值。这里我使用的是间接法。间接法又存在一个问题,就是由旋转后图像的每一个位置反算到原图时,所在的坐标可能不是一个整数坐标。那么这个坐标我们给它的像素值就需要内插出来。

关于内插,又分为最近邻元法,双线性内插法,三次内插法。这里使用的是双线性内插法,它的算法简单来说,就是根据距离周围四个像素值的远近,离得越近,权重越大,来内插一个像素值。(个人理解,仅供参考)

示例图像

...

素描算法(图像处理)

素描算法介绍

素描算法其实就是几种简单的图像处理算法,对同一张图片进行处理后,产生的一种类似素描的算法。这里简单的描述一下他的原理。

  1. 彩色图像进行类似直方图均衡化处理,增强图像的对比度,使得图像的轮廓更加分明。
  2. 将步骤 1 处理后的彩色图像进行灰度处理得到图像 gray。
  3. 将得到的图像 gray 复制一份得到图像 gray1。
  4. 将图像 gray 的像素进行取反,得到负片效果。
  5. 对步骤 4 获得的图像进行高斯滤波处理。这里高斯滤波处理次数不同,最后的效果也不同。处理得到图像 guassian。
  6. 图像淡化生成素描图像 sketch。

处理的图像效果

图1 原图

图2 素描算法

...

[图形学] 画填充圆(基于 Bresenham 算法)

基于图形学中的 Bresenham 画圆法,设计了填充圆的实现。以下是该实现的 C 语言源码:

///////////////////////////////////////////////////
// 程序名称:基于 Bresenham 算法画填充圆
// 编译环境:Visual C++ 6.0 / 2013,EasyX 20140321(beta)
// 作  者:yangw80 <yw80@qq.com>
// 最后修改:2014-7-14
//
#include <graphics.h>
#include <conio.h>

// 基于 Bresenham 算法画填充圆
void FillCircle_Bresenham(int x, int y, int r, COLORREF color)
{
	int tx = 0, ty = r, d = 3 - 2 * r, i;

	while( tx < ty)
	{
		// 画水平两点连线(<45度
...

[图像处理] 将图片转换为马赛克效果

这个程序将图片转换为马赛克效果。

算法原理:求出每个小方块内所有像素的颜色平均值,然后用来设置为该小方块的颜色。依次处理每个小方块,即可实现马赛克效果。

完整代码如下:

/////////////////////////////////////////////////////////
// 程序名称:将图片转换为马赛克效果
// 编译环境:Visual C++ 6.0 / 2010,EasyX_20200727
// 作    者:krissi <zh@easyx.cn>
// 最后修改:2013-4-22
//
#include <graphics.h>
#include <conio.h>

// 将图片转换为马赛克效果
// 参数:
//		pimg: 待处理的 IMAGE 对象指针
//		tilesize: 马赛克的尺寸
//		startx: 马赛克的平铺起始位置 x 坐标
//		starty: 马赛克的平铺起始位置 y 坐标
vo
...

[图像处理] 将图片进行模糊处理

这个程序实现将图片进行模糊处理。

本程序的模糊处理算法:遍历图片像素,将每个像素颜色值与其周围像素颜色值求和,取平均值对其赋值。

完整代码如下(注意图片文件的路径):

/////////////////////////////////////////////////////////////////////////
// 程序名称:将图片进行模糊处理
// 编译环境:Visual C++ 6.0 ~ 2017,EasyX 20180727(beta)
// 作  者:krissi <zh@easyx.cn>
// 发布日期:2013-1-19
// 最后修改:2018-10-5
//
#include <graphics.h>
#include <conio.h>				

// 将图片进行模糊处理
void Blur(IMAGE *pimg)
{
	DWORD*	pMem = GetImageBuffer(pimg);

	int	r, g, b
...

[图像处理] 彩色图片转化成底片效果

这个程序实现将图片转化成底片效果。

底片效果使用如下公式:

R = 0xFF - GetRValue(pMem[i]);

G = 0xFF - GetGValue(pMem[i]);

B = 0xFF - GetBValue(pMem[i]);

完整代码如下:

/////////////////////////////////////////////////////////
// 程序名称:底片效果
// 编译环境:Visual C++ 6.0 / 2010,EasyX_20200727
// 作    者:krissi <zh@easyx.cn>
// 最后修改:2013-1-20
//
#include <graphics.h>
#include <conio.h>

// 底片效果
void ColorInvert(IMAGE *pimg)
{	
...

[图像处理] 彩色图像转换为灰度图像

这个程序实现将彩色图像转换为灰度图像。

彩色转换为灰度使用如下公式:

Gray = R * 0.299 + G * 0.587 + B * 0.114

为了提高运算速度,将这个公式转换为整数运算:

Gray = (R * 229 + G * 587 + B * 114 + 500) / 1000

为了提高运算速度的方法还有很多,这里作为演示,不再详述。

完整代码如下:

/////////////////////////////////////////////////////////
// 程序名称:彩色图片转换为灰阶图片
// 编译环境:Visual C++ 6.0 / 2010,EasyX 20130322(beta)
// 作    者:krissi <zh@easyx.cn>
// 最后修改:2013-
...

[图形学] 画圆(基于 Bresenham 算法)

图形学中的 Bresenham 画圆算法是基于中点画圆算法的派生,以下是该算法的 C 语言实现:

///////////////////////////////////////////////////
// 程序名称:基于 Bresenham 算法画圆
// 编译环境:Visual C++ 6.0 / 2010,EasyX_20210730
// 作  者:YangW <yw80@qq.com>
// 最后修改:2011-5-3
//
#include <graphics.h>
#include <conio.h>

// 使用 Bresenham 画圆法
void Circle_Bresenham(int x, int y, int r, int color)
{
	int tx = 0, ty = r, d = 3 - 2 * r;

	while( tx <= ty)
	{
		// 利用圆的八分对称性画点
		putpixel(x + tx, y + ty, 
...

[图形学] 画圆(基于正负算法)

图形学中的正负画圆算法,以下是该算法的 C 语言实现:

///////////////////////////////////////////////////
// 程序名称:基于正负算法画圆
// 编译环境:Visual C++ 6.0 / 2010,EasyX_20210115
// 作  者:YangW <yw80@qq.com>
// 最后修改:2011-5-3
//
#include <graphics.h>
#include <conio.h>

// 正负画圆法
void Circle_PN(int x, int y, int r, int color)
{
	int tx = 0, ty = r, f = 0;

	while(tx <= ty)
	{
		// 利用圆的八分对称性画点
		putpixel(x + tx, y + ty, color);
		putpixel(x + tx, y - ty, color);
		putpixel(x -
...

[图形学] 画圆(基于中点算法)

图形学中的中点画圆算法,以下是该算法的 C 语言实现:

///////////////////////////////////////////////////
// 程序名称:基于中点算法画圆
// 编译环境:Visual C++ 6.0 / 2010,EasyX_20210730
// 作  者:YangW <yw80@qq.com>
// 最后修改:2011-4-29
//
#include <graphics.h>
#include <conio.h>

// 中点画圆法
void Circle_Midpoint(int x, int y, int r, int color)
{
	int tx = 0, ty = r, d = 1 - r;

	while(tx <= ty)
	{
		// 利用圆的八分对称性画点
		putpixel(x + tx, y + ty, color);
		putpixel(x + tx, y - ty, color);
		p
...

[图形学] 画任意斜率的直线(基于 Bresenham 算法)

图形学中的 Bresenham 画直线算法,以下是该算法的 C 语言实现:

///////////////////////////////////////////////////
// 程序名称:基于 Bresenham 算法画任意斜率的直线
// 编译环境:Visual C++ 6.0 / 2010,EasyX 2011惊蛰版
// 作  者:yangw80 <yw80@qq.com>
// 发布日期:2011-4-26
//
#include <graphics.h>
#include <conio.h>

// 使用 Bresenham 算法画任意斜率的直线(包括起始点,不包括终止点)
void Line_Bresenham(int x1, int y1, int x2, int y2, int color)
{
	int x = x1;
	int y = y1;
	int dx = abs(x2 - x1);
	int dy = abs(y2 - y1);
	int
...

[图形学] 画任意斜率的直线(基于中点算法)

图形学中的直线的中点算法,以下是该算法的 C 语言实现:

///////////////////////////////////////////////////
// 程序名称:基于中点算法画任意斜率的直线
// 编译环境:Visual C++ 6.0 / 2010,EasyX 2011惊蛰版
// 作  者:yangw80 <yw80@qq.com>
// 最后修改:2011-4-26
//
#include <graphics.h>
#include <conio.h>

// 使用中点算法画任意斜率的直线(包括起始点,不包括终止点)
void Line_Midpoint(int x1, int y1, int x2, int y2, int color)
{
	int x = x1, y = y1;
	int a = y1 - y2, b = x2 - x1;
	int cx = (b >= 0 ? 1 : (b = -b, -1));
	int cy = (a
...

[图形学] 画任意斜率的直线(基于 DDA 算法)

图形学中的 DDA (Digital Differential Analyzer) 画直线算法,以下是该算法的 C 语言实现:

///////////////////////////////////////////////////
// 程序名称:基于 DDA 算法画任意斜率的直线
// 编译环境:Visual C++ 6.0 / 2010,EasyX 2011惊蛰版
// 作  者:yangw80 <yw80@qq.com>
// 最后修改:2011-4-26
//
#include <graphics.h>
#include <conio.h>

// 四舍五入
int Round(float x)
{
	return (int)(x < 0 ? x - 0.5 : x + 0.5);
}

// 使用 DDA 算法画任意斜率的直线(包括起始点,不包括终止点)
void Line_DDA(int x1, int y1, int x2, int y2, int co
...