2014-07-19 00:40:57 helloUSB2010 阅读数 25613
  • JavaSE案例--四连棋游戏--位运算

    传统的四连棋算法,使用的是两维数组的方式,这种算法非常的复杂和繁琐。 这套视频,采用位运算,& | << |= 等进行四连棋的游戏开发,运算性能非常快。 这是位运算使用的经典案例!(本套视频只提供算法分析代码,不提供项目演示代码)

    3092 人正在学习 去看看 肖海鹏

一、RGB

RGB色彩模式使用RGB模型为图像中每一个像素的RGB分量分配一个0~255范围内的强度值。RGB图像只使用三种颜色,R(red)、G(green)、B(blue),就可以使它们按照不同的比例混合,在屏幕上呈现16777216(256 * 256 * 256)种颜色。

在电脑中,RGB的所谓“多少”就是指亮度,并使用整数来表示。通常情况下,RGB各有256级亮度,用数字表示为从0、1、2...直到255。


二、ARGB

一种色彩模式,也就是RGB色彩模式附加上Alpha(透明度)通道,常见于32位位图存储结构
ARGB---Alpha,Red,Green,Blue.


三、灰度化

 在RGB模型中,如果R=G=B时,则彩色表示一种灰度颜色,其中R=G=B的值叫灰度值,因此,灰度图像每个像素只需一个字节存放灰度值(又称强度值、亮度值),灰度范围为0-255。一般有以下四种方法对彩色图像进行灰度化,具体方法参考:http://blog.csdn.net/evsqiezi/article/details/7905436   


四、二值化

一幅图像包括目标物体、背景还有噪声,要想从多值的数字图像中直接提取出目标物体,最常用的方法就是设定一个全局的阈值T,用T将图像的数据分成两部分:大于T的像素群和小于T的像素群。将大于T的像素群的像素值设定为白色(或者黑色),小于T的像素群的像素值设定为黑色(或者白色)。
比如:计算每一个像素的(R+G+B)/3,如果>127,则设置该像素为白色,即R=G=B=255;否则设置为黑色,即R=G=B=0。
C#实现代码如下:
public Bitmap binarization()
        {
            Bitmap bitImage = new Bitmap(pictureBox1.Image);//二值化pictureBox1中的图片
            Color c;
            int height = pictureBox1.Image.Height;
            int width = pictureBox1.Image.Width;
            for (int i = 0; i < height; i++)
            {
                for (int j = 0; j < width; j++)
                {
                    c = bitImage.GetPixel(j,i);
                    int r = c.R;
                    int g = c.G;
                    int b = c.B;
                    if ((r + g + b) / 3 >= 127)
                    {                       
                        bitImage.SetPixel(j, i, Color.FromArgb(255, 255, 255));                  
                    }
                    else
                    {     
                        bitImage.SetPixel(j, i, Color.FromArgb(0,0,0));
                    }
                }
            }
            return bitImage;
        }
运行结果如图:
左边为处理前,右边为二值化后效果。


五、膨胀算法

膨胀是将与物体接触的所有背景点合并到该物体中,使边界向外部扩张的过程。

可以用来填补物体中的空洞。

 

3x3的结构元素,扫描图像的每一个像素

用结构元素与其覆盖的二值图像做操作

如果都为0,结果图像的该像素为0。否则为1

结果:使二值图像扩大一圈


膨胀(dilation)可以看做是腐蚀的对偶运算,其定义是:把结构元素B平移a后得到Ba,若Ba击中X,我们记下这个a点。所有满足上述条件的a点组成的集合称做XB膨胀的结果。用公式表示为:D(X)={a | BaX}=X腐蚀,膨胀,细化算法B,如下图所示。图X是被处理的对象,B是结构元素,不难知道,对于任意一个在阴影部分的点aBa击中X,所以XB膨胀的结果就是那个阴影部分。阴影部分包括X的所有范围,就象X膨胀了一圈似的,这就是为什么叫膨胀的原因。



在下图中,左边是被处理的图象X(二值图象,我们针对的是黑点),中间是结构元素B。膨胀的方法是,拿B的中心点和X上的点及X周围的点一个一个地对,如果B上有一个点落在X的范围内,则该点就为黑;右边是膨胀后的结果。可以看出,它包括X的所有范围,就象X膨胀了一圈似的。




我设计了一个简单的膨胀算法,依次遍历整个图片的像素,分析每一个像素的周围八个像素,只要该像素周围存在黑色的像素,就设置该像素颜色为黑色。下面是使用膨胀算法处理经过二值化后的图像的C#实现代码:

public bool[] getRoundPixel(Bitmap bitmap, int x, int y)//返回(x,y)周围像素的情况,为黑色,则设置为true
        {
            bool[] pixels=new bool[8];
            Color c;
            int num = 0;
            for (int i = -1; i < 2; i++)
            {
                for (int j = -1; j < 2; j++)
                {
                    c = bitmap.GetPixel(x+i,y+j);
                    if (i != 0 || j != 0)
                    {
                        if (255 == c.G)//因为经过了二值化,所以只要检查RGB中一个属性的值
                        {
                            pixels[num] = false;//为白色,设置为false
                            num++;
                        }
                        else if(0==c.G)
                        {
                            pixels[num] = true;//为黑色,设置为true
                            num++;
                        }
                    }
                }
            }
            return pixels;
        }


public Bitmap expend()
        {
            Bitmap bitImage = new Bitmap(pictureBox2.Image);//处理pictureBox2中的图片
            Bitmap bitImage1 = new Bitmap(pictureBox2.Image);
            int height = pictureBox1.Image.Height;
            int width = pictureBox1.Image.Width;
            bool[] pixels;
            for (int i = 1; i < width-1; i++)
            {
                for (int j = 1; j < height-1; j++)
                {
                    
                    if (bitImage.GetPixel(i, j).R != 0)
                    {
                        pixels = getRoundPixel(bitImage, i, j);
                        for (int k = 0; k < pixels.Length; k++)
                        {
                            if (pixels[k] == true)
                            {
                                //set this piexl's color to black
                                bitImage1.SetPixel(i, j, Color.FromArgb(0,0,0));
                                break;
                            }
                        }
                    }
                }
            }
                return bitImage1;

        }


运行结果如图:


六、腐蚀算法


腐蚀是一种消除边界点,使边界向内部收缩的过程。可以用来消除小且无意义的物体。



3x3的结构元素,扫描图像的每一个像素


用结构元素与其覆盖的二值图像做操作


如果都为1,结果图像的该像素为1。否则为0


结果:使二值图像减小一圈

把结构元素B平移a后得到Ba,若Ba包含于X,我们记下这个a点,所有满足上述条件的a点组成的集合称做XB腐蚀(Erosion)的结果。用公式表示为:E(X)={a| Ba 腐蚀,膨胀,细化算法X}=X 腐蚀,膨胀,细化算法B。



下图中X是被处理的对象,B是结构元素。不难知道,对于任意一个在阴影部分的点aBa包含于X,所以XB腐蚀的结果就是那个阴影部分。阴影部分在X的范围之内,且比X小,就象X被剥掉了一层似的,这就是为什么叫腐蚀的原因。


我设计了一个简单的腐蚀算法,一次遍历图像中每一个像素,检查它四周的八个像素,如果有白色的像素,则设置改点为白色。用二值化处理后的图片进行腐蚀算法C#代码如下:


public Bitmap corrode()
        {
            Bitmap bitImage = new Bitmap(pictureBox2.Image);
            Bitmap bitImage1 = new Bitmap(pictureBox2.Image);
            Color c;
            int height = pictureBox1.Image.Height;
            int width = pictureBox1.Image.Width;
            bool[] pixels;
            for (int i = 1; i < width - 1; i++)
            {
                for (int j = 1; j < height - 1; j++)
                {
                    c = bitImage.GetPixel(i, j);
                    if (bitImage.GetPixel(i, j).R == 0)
                    {
                        pixels = getRoundPixel(bitImage, i, j);
                        for (int k = 0; k < pixels.Length; k++)
                        {
                            if (pixels[k] == false)
                            {
                                //set this piexl's color to black
                                bitImage1.SetPixel(i, j, Color.FromArgb(255, 255, 255));
                                break;
                            }
                        }
                    }
                }
            }
            return bitImage1;
        }

处理后图片变成:



七、开运算

先腐蚀后膨胀的过程称为开运算。用来消除小物体、在纤细点处分离物体、平滑较大物体的边界的同时并不明显改变其面积。


八、闭运算

先膨胀后腐蚀的过程称为闭运算。用来填充物体内细小空洞、连接邻近物体、平滑其边界的同时并不明显改变其面积。



2018-11-02 12:21:25 Eastmount 阅读数 4233
  • JavaSE案例--四连棋游戏--位运算

    传统的四连棋算法,使用的是两维数组的方式,这种算法非常的复杂和繁琐。 这套视频,采用位运算,& | << |= 等进行四连棋的游戏开发,运算性能非常快。 这是位运算使用的经典案例!(本套视频只提供算法分析代码,不提供项目演示代码)

    3092 人正在学习 去看看 肖海鹏

该系列文章是讲解Python OpenCV图像处理知识,前期主要讲解图像入门、OpenCV基础用法,中期讲解图像处理的各种算法,包括图像锐化算子、图像增强技术、图像分割等,后期结合深度学习研究图像识别、图像分类应用。希望文章对您有所帮助,如果有不足之处,还请海涵~

该系列在github所有源代码:https://github.com/eastmountyxz/ImageProcessing-Python
PS:请求帮忙点个Star,哈哈,第一次使用Github,以后会分享更多代码,一起加油。

同时推荐作者的C++图像系列知识:
[数字图像处理] 一.MFC详解显示BMP格式图片
[数字图像处理] 二.MFC单文档分割窗口显示图片
[数字图像处理] 三.MFC实现图像灰度、采样和量化功能详解
[数字图像处理] 四.MFC对话框绘制灰度直方图
[数字图像处理] 五.MFC图像点运算之灰度线性变化、灰度非线性变化、阈值化和均衡化处理详解
[数字图像处理] 六.MFC空间几何变换之图像平移、镜像、旋转、缩放详解
[数字图像处理] 七.MFC图像增强之图像普通平滑、高斯平滑、Laplacian、Sobel、Prewitt锐化详解

前文参考:
[Python图像处理] 一.图像处理基础知识及OpenCV入门函数
[Python图像处理] 二.OpenCV+Numpy库读取与修改像素
[Python图像处理] 三.获取图像属性、兴趣ROI区域及通道处理
[Python图像处理] 四.图像平滑之均值滤波、方框滤波、高斯滤波及中值滤波
[Python图像处理] 五.图像融合、加法运算及图像类型转换
[Python图像处理] 六.图像缩放、图像旋转、图像翻转与图像平移
[Python图像处理] 七.图像阈值化处理及算法对比
[Python图像处理] 八.图像腐蚀与图像膨胀

数学形态学(Mathematical morphology)是一门建立在格论和拓扑学基础之上的图像分析学科,是数学形态学图像处理的基本理论。其基本的运算包括:腐蚀和膨胀、开运算和闭运算、骨架抽取、极限腐蚀、击中击不中变换、形态学梯度、Top-hat变换、颗粒分析、流域变换等。

本篇文章主要讲解Python调用OpenCV实现图像形态学转化,包括图像开运算、图像闭运算和梯度运算,基础性知识希望对您有所帮助。
1.图像开运算
2.图像闭运算
3.图像梯度运算

PS:文章参考自己以前系列图像处理文章及OpenCV库函数,同时部分参考网易云lilizong老师的视频,推荐大家去学习。同时,本篇文章涉及到《计算机图形学》基础知识,请大家下来补充。

PSS:2019年1~2月作者参加了CSDN2018年博客评选,希望您能投出宝贵的一票。我是59号,Eastmount,杨秀璋。投票地址:https://bss.csdn.net/m/topic/blog_star2018/index

五年来写了314篇博客,12个专栏,是真的热爱分享,热爱CSDN这个平台,也想帮助更多的人,专栏包括Python、数据挖掘、网络爬虫、图像处理、C#、Android等。现在也当了两年老师,更是觉得有义务教好每一个学生,让贵州学子好好写点代码,学点技术,"师者,传到授业解惑也",提前祝大家新年快乐。2019我们携手共进,为爱而生。

一. 图像开运算

1.基本原理
图像开运算是图像依次经过腐蚀、膨胀处理后的过程。图像被腐蚀后,去除了噪声,但是也压缩了图像;接着对腐蚀过的图像进行膨胀处理,可以去除噪声,并保留原有图像。如下图所示:

开运算(img) = 膨胀( 腐蚀(img) )
下图是hanshanbuleng博主提供的开运算效果图,推荐大家学习他的文章。

https://blog.csdn.net/hanshanbuleng/article/details/80657148

2.函数原型
图像开运算主要使用的函数morphologyEx,它是形态学扩展的一组函数,其参数cv2.MORPH_OPEN对应开运算。其原型如下:
dst = cv2.morphologyEx(src, cv2.MORPH_OPEN, kernel)

参数dst表示处理的结果,src表示原图像,cv2.MORPH_OPEN表示开运算,kernel表示卷积核。下图表示5*5的卷积核,可以采用函数 np.ones((5,5), np.uint8) 构建。

运行结果如下图所示:

3.代码实现
完整代码如下所示:

#encoding:utf-8
import cv2  
import numpy as np  

#读取图片
src = cv2.imread('test01.png', cv2.IMREAD_UNCHANGED)

#设置卷积核
kernel = np.ones((5,5), np.uint8)

#图像开运算
result = cv2.morphologyEx(src, cv2.MORPH_OPEN, kernel)

#显示图像
cv2.imshow("src", src)
cv2.imshow("result", result)

#等待显示
cv2.waitKey(0)
cv2.destroyAllWindows()

输出结果如下图所示,可以看到噪声已经被去除了。

但是结果result中仍然有部分噪声,如果想去除更彻底将卷积设置为10*10的。 kernel = np.ones((10,10), np.uint8) result = cv2.morphologyEx(src, cv2.MORPH_OPEN, kernel)


二. 图像闭运算

1.基本原理
图像闭运算是图像依次经过膨胀、腐蚀处理后的过程。图像先膨胀,后腐蚀,它有助于关闭前景物体内部的小孔,或物体上的小黑点。如下图所示:

闭运算(img) = 腐蚀( 膨胀(img) )
下图是hanshanbuleng博主提供的开运算效果图,推荐大家学习他的文章。

https://blog.csdn.net/hanshanbuleng/article/details/80657148

2.函数原型
图像闭运算主要使用的函数morphologyEx,其原型如下:
dst = cv2.morphologyEx(src, cv2.MORPH_CLOSE, kernel)

参数dst表示处理的结果,src表示原图像, cv2.MORPH_CLOSE表示闭运算,kernel表示卷积核。下图表示5*5的卷积核,可以采用函数 np.ones((5,5), np.uint8) 构建。

运行结果如下图所示:

3.代码实现
完整代码如下所示:

#encoding:utf-8
import cv2  
import numpy as np  

#读取图片
src = cv2.imread('test03.png', cv2.IMREAD_UNCHANGED)

#设置卷积核
kernel = np.ones((10,10), np.uint8)

#图像闭运算
result = cv2.morphologyEx(src, cv2.MORPH_CLOSE, kernel)

#显示图像
cv2.imshow("src", src)
cv2.imshow("result", result)

#等待显示
cv2.waitKey(0)
cv2.destroyAllWindows()

输出结果如下图所示,可以看到中间的噪声去掉。



三. 图像梯度运算

1.基本原理
图像梯度运算是膨胀图像减去腐蚀图像的结果,得到图像的轮廓,其中二值图像1表示白色点,0表示黑色点。如下图所示:

梯度运算(img) = 膨胀(img) - 腐蚀(img)

2.函数原型
图像梯度运算主要使用的函数morphologyEx,参数为cv2.MORPH_GRADIENT。其原型如下:
dst = cv2.morphologyEx(src, cv2.MORPH_GRADIENT, kernel)

参数dst表示处理的结果,src表示原图像, cv2.MORPH_GRADIENT表示梯度运算,kernel表示卷积核。5*5的卷积核可以采用函数 np.ones((5,5), np.uint8) 构建。
运行结果如下图所示:

3.代码实现
完整代码如下所示:

#encoding:utf-8
import cv2  
import numpy as np  

#读取图片
src = cv2.imread('test04.png', cv2.IMREAD_UNCHANGED)

#设置卷积核
kernel = np.ones((10,10), np.uint8)

#图像闭运算
result = cv2.morphologyEx(src, cv2.MORPH_GRADIENT, kernel)

#显示图像
cv2.imshow("src", src)
cv2.imshow("result", result)

#等待显示
cv2.waitKey(0)
cv2.destroyAllWindows()

输出结果如下图所示,可以看到中间的噪声去掉。

希望文章对大家有所帮助,如果有错误或不足之处,还请海涵。最近经历的事情太多,有喜有悲,关闭了朋友圈,希望通过不断学习和写文章来忘记烦劳,将忧郁转换为动力,每周学习都记录下来,加油!!!
(By:Eastmount 2018-11-02 中午12点 https://blog.csdn.net/Eastmount/)

2018-04-10 00:00:51 weixin_39569242 阅读数 2569
  • JavaSE案例--四连棋游戏--位运算

    传统的四连棋算法,使用的是两维数组的方式,这种算法非常的复杂和繁琐。 这套视频,采用位运算,& | << |= 等进行四连棋的游戏开发,运算性能非常快。 这是位运算使用的经典案例!(本套视频只提供算法分析代码,不提供项目演示代码)

    3092 人正在学习 去看看 肖海鹏

实验一 图像的基本运算

一、实验目的

1)掌握点运算和代数运算的算法实现和概念

2)掌握和几何运算的算法实现和概念

2)掌握灰度变换和几何变换的基本方法

3)理解图像灰度直方图的概念

二、实验内容

1)任意选择几幅图像,查看其直方图,说明直方图和图像的对应关系。

2)任意选择几幅图像,对其进行灰度线性变换,结合以下情况分析输入图像和输出图像两者有何变化。

Ø  当斜率a>1时;

Ø  当斜率 a<1时;

Ø  当斜率a1b<0时;

Ø  当斜率a1b>0时;

Ø  当斜率a1b=0时;

Ø  当斜率a-1b=255时;

3)选择几幅图像,对其进行灰度拉伸,选择不同的拉伸参数,观察图像与原图有何不同,总结灰度拉伸的原理。

4)选择几幅图像对其进行几何变换,理解不同变换对图像产生的影响。

三、实验代码、结果、分析

1代码:

I=imread('C:\Users\xxxy\Desktop\1.jpg'); imshow(I)

I=rgb2gray(I); %真彩色图像转换为灰度图像,即灰度化处理

add=[];  tab1=zeros(1,256);

for n=0:255

    X=I==n;      add=[add;sum(sum(X))];

end;  

[a b]=size(I);   final=add/(a*b);

figure; imshow(I);

figure;  bar(0:255,final,'g')

figure; imhist(I)

结果:

                

1-1:原图                                                      1-2:灰度图

            

1-3 直方图                                                        1-4 纵坐标扩大直方图

分析:灰度直方图描述了该灰度级的像素的个数,其横坐标是灰度级,纵坐标是该灰度级出现的概率,eg:灰度值为100的概率可近似看做0.004

2代码

I=imread('C:\Users\xxxy\Desktop\2.jpg');    imshow(I)

y=a*I+b/255;    %线性点运算

figure   subplot(2,2,1);    imshow(y);

 

2-1  原图

a,b值分别如下,及结果图:

[1]a=2;b=10;                             [2]a=0.3;b=1;

             

2-2:a>1                                 2-3a<1

[3]a=1;b=-10;             [4]a=1;b=10;              [5]a=1;b=0;

       

2-4a1b<0        2-5a1b>0          2-6a1b=0

[7]a=-1;b=255;

 

                                               图2-7a-1b=255

分析:

[1] 如果a>1,输出图像的对比度变大,即图像变得更亮

[2] 如果a<1,输出图像的对比度减小,即图像变得更暗

[3] 如果a=1,b<0,输出图像下移,图像显示的更暗

[4] 如果a=1,b>0,输出图像上移,图像显示的更亮

[5] 如果a=1,b=0,输出图像不变,与原图像一样

[6] 如果a=1,b<0,输出图像下移,图像显示的更暗

[7] 如果a<0,b<0,输出图像亮区变暗,暗区变亮

3代码:

I=imread('C:\Users\xxxy\Desktop\3.jpg');imshow(I)

Y=double(I);  %将参数I转为双精度浮点类型

[M,N]=size(Y);

for i=1:M          

    for j=1:N              

        if Y(i,j)<=30                 

            Y(i,j)=I(i,j);             

        else if Y(i,j)<=150                  

                Y(i,j)=(200-30)/(160-30)*(I(i,j)-30)+30;            

            else   Y(i,j)=(255-200)/(255-150)*(I(i,j)-150)+200;             

            end

        end

    end

end

    figure(2);     imshow(uint8(Y))

结果:

                    

       3-1:原图                                     图3-2:灰度拉伸

分析:

将其小于30的灰度值不变,将30150的灰度值拉伸到30200,同时压缩150255的灰度值到200255之间

4代码:

I=imread('C:\Users\xxxy\Desktop\4.jpg'); imshow(I);  figure;

se = translate(strel(1), [100 100]);  

a = imdilate(I,se);     imshow(a)%平移      figure;

b = imresize(I,1.5)     imshow(b)%放大1.5   figure;

c= imresize(I,0.5)      imshow(c)%缩小0.5    figure;

[height,width,dim]=size(I);

tform1=maketform('affine',[-1 0 0;0 1 0;width 0 1]);

d1=imtransform(I,tform1,'nearest');  imshow(d1);%水平镜像 figure;

tform2=maketform('affine',[1 0 0;0 -1 0;0 height 1]);

d2=imtransform(I,tform2,'nearest');  imshow(d2);%垂直镜像 figure;

e1 = imrotate(I,90);  imshow(e1)%旋转90    figure;

e2 = imrotate(I,180); imshow(e2)%旋转180   figure;

e3 = imrotate(I,270);  imshow(e3)%旋转270  figure;

e4 = imrotate(I,360);  imshow(e4)%旋转360  figure;

          

        图4-1:原图                                  图4-2:平移

           

        图4-3:放大1.5                                                4-4:缩小0.5

                

           图4-5:水平镜像                                4-5:垂直镜像

            

              4-7:旋转90度                                       4-8:旋转180

                    

            图4-9:旋转270度                            4-10:旋转360度  

2016-06-06 17:34:31 xueyedie1234 阅读数 23286
  • JavaSE案例--四连棋游戏--位运算

    传统的四连棋算法,使用的是两维数组的方式,这种算法非常的复杂和繁琐。 这套视频,采用位运算,& | << |= 等进行四连棋的游戏开发,运算性能非常快。 这是位运算使用的经典案例!(本套视频只提供算法分析代码,不提供项目演示代码)

    3092 人正在学习 去看看 肖海鹏

本文索引:

文章目录





# 一、 什么是卷积?       在图像处理中,卷积操作指的是使用一个卷积核对图像中的每个像素进行一系列操作。       卷积核(算子)是用来做图像处理时的矩阵,图像处理时也称为掩膜,是与原图像做运算的参数。卷积核通常是一个四方形的网格结构(例如3*3的矩阵或像素区域),该区域上每个方格都有一个权重值。       使用卷积进行计算时,需要将卷积核的中心放置在要计算的像素上,一次计算核中每个元素和其覆盖的图像像素值的乘积并求和,得到的结构就是该位置的新像素值。       以下两个算子中演示了具体的卷积计算过程。
# 二、 相关算子 定义:![这里写图片描述](http://img.blog.csdn.net/20160603125126517) 即![这里写图片描述](http://img.blog.csdn.net/20160603125155767),其中h称为相关核(Kernel).          步骤:
  • 1)滑动核,使其中心位于输入图像g的(i,j)像素上
  • 2)利用上式求和,得到输出图像的(i,j)像素值
  • 3)充分上面操纵,直到求出输出图像的所有像素值

【例】
  原始像素矩阵为:
\begin{bmatrix}
17 & 24 & 1 & 8 & 15 \
23 & 5 & 7 & 14 & 16 \
4 & 6 & 13 & 20 & 22 \
10 & 12 & 19 & 21 & 3\
11 & 18 & 25 & 2 & 9
\end{bmatrix}

卷积模板h为:
\begin{bmatrix}
8 & 1 & 6 \
3 & 5 & 7 \
4 & 9 & 2
\end{bmatrix}

计算输出图像的(2,4)元素=18+81+156+73+145+167+134+209+22*2=585
如图所示:
这里写图片描述


# 三、 卷积算子

定义:这里写图片描述
这里写图片描述

步骤:

  • 1)将核围绕中心旋转180度
  • 2)滑动核,使其中心位于输入图像g的(i,j)像素上
  • 3)利用上式求和,得到输出图像的(i,j)像素值
  • 4)充分上面操纵,直到求出输出图像的所有像素值
    例:计算输出图像的(2,4)元素=12+89+154+77+145+163+136+201+22*8=575
    如图所示:
    这里写图片描述

# 四、 边缘效应       当对图像边缘的进行滤波时,核的一部分会位于图像边缘外面。 ![这里写图片描述](http://img.blog.csdn.net/20160603143253118) 常用的策略包括: - 1)使用常数填充:imfilter默认用0填充,这会造成处理后的图像边缘是黑色的。 - 2)复制边缘像素:I3 = imfilter(I,h,'replicate'); ![这里写图片描述](http://img.blog.csdn.net/20160603143353525)
# 五、 常用的卷积核及其用途
  • 1)低通滤波器(常用于计算模糊后的效果)\begin{bmatrix}
    1/9 & 1/9 & 1/9 \
    1/9 & 1/9 & 1/9 \
    1/9 & 1/9 & 1/9
    \end{bmatrix}
    \begin{bmatrix}
    1/10 & 1/10 & 1/10 \
    1/10 & 2/10 & 1/10 \
    1/10 & 1/10 & 1/10
    \end{bmatrix}
    \begin{bmatrix}
    1/16 & 2/16 & 1/16 \
    2/16 & 4/16 & 2/16 \
    1/16 & 2/16 & 1/16
    \end{bmatrix}

  • 2)高斯滤波器(常用于计算高斯模糊后的效果)
          高斯模糊的卷积核也是一个正方形的滤波核,其中每个元素通过以下公式计算得出:
          G(x,y)=12πσ2ex2+y22σ2G(x,y)=\frac{1}{2πσ^{2}}·e^{\frac{x^{2}+y^{2}}{2σ^{2}}}
          该公式中σ是标准方差(一般取值为1),x和y分别对应了当前位置到卷积核中心的整数距离。通过这个公式,就可以计算出高斯核中每个位置对应的值。为了保证滤波后的图像不会变暗,需要对高斯核中的权重进行归一化。

  • 3)边缘检测(常用于计算图像边缘或者说梯度值)
    \begin{bmatrix}
    -1 & 0 & -1 \
    0 & 4 & 0 \
    -1 & 0 & -1
    \end{bmatrix}


# 六、 一个例子——使用卷积实现模糊效果       我们将对下面这张图进行模糊处理: ![这里写图片描述](http://img.blog.csdn.net/20160606172529227)       以下为compute shader中关于卷积处理的代码:
[numthreads(32,32,1)]
void Dim_Main (uint3 id : SV_DispatchThreadID)
{

	float sumR = 0;
	float sumG = 0;
	float sumB = 0;
	float sumA = 0;
	for (int i = -1; i <= 1; i++) 
	{
		for (int j = -1; j <= 1; j++) 
		{
			sumR += texBuffer[(id.x+i)*texWidth[0]+(id.y+j)].r * convolutionTempBuffer[(i+1)*3+(j+1)];
			sumG += texBuffer[(id.x+i)*texWidth[0]+(id.y+j)].g * convolutionTempBuffer[(i+1)*3+(j+1)];
			sumB += texBuffer[(id.x+i)*texWidth[0]+(id.y+j)].b * convolutionTempBuffer[(i+1)*3+(j+1)];
			sumA += texBuffer[(id.x+i)*texWidth[0]+(id.y+j)].a * convolutionTempBuffer[(i+1)*3+(j+1)];
		}
	}

	texBuffer[id.x*texWidth[0]+id.y].r = sumR;
	texBuffer[id.x*texWidth[0]+id.y].g = sumG;
	texBuffer[id.x*texWidth[0]+id.y].b = sumB;
	texBuffer[id.x*texWidth[0]+id.y].a = sumA;

	Result[id.xy] = float4(sumR, sumG, sumB, sumA);
}

效果如图所示:
这里写图片描述

      图中可以明显的看到左右两边有明显的黑色线条,原图中是没有这样的黑色的,产生这种效果的原因是本文中之前提到过的边缘效应。下面我将修改一部分代码去除边缘效应带来的影响,这里使用的是相邻像素的值方法。
代码如下:

[numthreads(32,32,1)]
void Dim_Main (uint3 id : SV_DispatchThreadID)
{

	float sumR = 0;
	float sumG = 0;
	float sumB = 0;
	float sumA = 0;
	for (int i = -1; i <= 1; i++) 
	{
		for (int j = -1; j <= 1; j++) 
		{
			if((id.x+i)*texWidth[0]+(id.y+j)>texWidth[0]*texWidth[0]-1)
			{
				sumR += texBuffer[(id.x+i)*texWidth[0]+(id.y+j)-texWidth[0]].r * convolutionTempBuffer[(i+1)*3+(j+1)];
				sumG += texBuffer[(id.x+i)*texWidth[0]+(id.y+j)-texWidth[0]].g * convolutionTempBuffer[(i+1)*3+(j+1)];
				sumB += texBuffer[(id.x+i)*texWidth[0]+(id.y+j)-texWidth[0]].b * convolutionTempBuffer[(i+1)*3+(j+1)];
				sumA += texBuffer[(id.x+i)*texWidth[0]+(id.y+j)-texWidth[0]].a * convolutionTempBuffer[(i+1)*3+(j+1)];
			}

			sumR += texBuffer[(id.x+i)*texWidth[0]+(id.y+j)].r * convolutionTempBuffer[(i+1)*3+(j+1)];
			sumG += texBuffer[(id.x+i)*texWidth[0]+(id.y+j)].g * convolutionTempBuffer[(i+1)*3+(j+1)];
			sumB += texBuffer[(id.x+i)*texWidth[0]+(id.y+j)].b * convolutionTempBuffer[(i+1)*3+(j+1)];
			sumA += texBuffer[(id.x+i)*texWidth[0]+(id.y+j)].a * convolutionTempBuffer[(i+1)*3+(j+1)];
		}
	}

	texBuffer[id.x*texWidth[0]+id.y].r = sumR;
	texBuffer[id.x*texWidth[0]+id.y].g = sumG;
	texBuffer[id.x*texWidth[0]+id.y].b = sumB;
	texBuffer[id.x*texWidth[0]+id.y].a = sumA;

	Result[id.xy] = float4(sumR, sumG, sumB, sumA);
}

效果如图所示:
这里写图片描述

      可以看到,图中左边的黑色线条已经被滤除,右边也可以采用类似的方法来剔除。实际使用中,也可以根据情况使用纯色来做剔除,这样可以节省部分效率,如下图中我使用的是纯白色来剔除边缘效应。
这里写图片描述

2017-03-05 20:26:34 Mac_lzq 阅读数 16353
  • JavaSE案例--四连棋游戏--位运算

    传统的四连棋算法,使用的是两维数组的方式,这种算法非常的复杂和繁琐。 这套视频,采用位运算,& | << |= 等进行四连棋的游戏开发,运算性能非常快。 这是位运算使用的经典案例!(本套视频只提供算法分析代码,不提供项目演示代码)

    3092 人正在学习 去看看 肖海鹏
图像处理基本算法操作从处理对象的多少可以有如下划分:
一)点运算:处理点单元信息的运算
二)群运算:处理群单元 (若干个相邻点的集合)的运算
                                              表1 图像处理操作按处理对象数量分类表格
操作类型
具体常用操作
点运算
二值化操作、直方图处理、亮度映射、加法运算、
翻转运 算 、尺度运算 、对数运算 、指数运算等
群运算
模板卷积运算、滤波运算(均值滤波、最大值滤波 、最小值滤波)、
各项异性扩散、形态学操作(膨胀和腐蚀)、力场变换等
      下图是一副普通的吉普车图像和我们生活中见到的并没有什么两样,但是在计算机看来则是另外一副“模样”了。图像中黄色部分则是几部车图像倒车镜的局部图像在计算机中的形态。                                                
图1 计算机图像的真实表现形态
      以上图为例说明几种重要的点运算和群运算。
      1.二值化操作
       图像二值化是图像处理中十分常见且重要的操作,它是将灰度图像转换为二值图像或灰度图像的过程。二值化操作有很多种,例如一般二值化、翻转二值化、截断二值化、置零二值化、置零翻转二值化。
其中src(x,y)表示的是原始图像中第x行第y列像素值。 
       如果去图像中左上角3X3的邻域,thresh取200,maxval取255,阈值方法选择一般二值化(THRESH_BINARY),那么操作过后的结果如下:
                                                                                                                                                    
                                                                                                                                     图2 一般二值化图示
       在图2中,一般二值化下底表示为0,上顶表示为maxval,其中蓝色横线则表示阈值(thresh)。超过该阈值则为maxval,否则为0。
                                                                                                                     
                                                                                                            (a) 操作前                                                      (b) 操作后
     2.直方图处理 
       直方图是图像处理中另一重要处理过程,它反映图像中不同像素值的统计信息。从这句话我们可以了解到直方图信息仅反映灰度统计信息,与像素具体位置没有关系。这一重要特性在许多识别类算法中直方图处理起到关键作用。假设现有3X3的大小的图像。像素值分别为6,3,3,8,6,8,3,3,3,那么它的统计直方图则为
       假设图1中反光镜的直方图为下图所示。
               
                    图3 图像直方图
     假设我们对直方图中中某一灰度信息进行置零操作,那么反映在直方图图上则是该灰度的柱状高度为0。
     值得一说的是二值化处理和某些直方图处理属于不可逆运算,而亮度映射、加法运算、翻转运算 、尺度运算 、对数运算 、指数运算等皆属于可逆运算。
    
     3.模板卷积运算
       模板运算是图像处理中使用频率相当高的一种运算,很多操作可以归结为模板运算,例如平滑处理,滤波处理以及边缘特征提取处理等。这里需要说明的是模板运算所使用的模板通常说来就是NXN的矩阵(N一般为奇数如3,5,7,...),如果这个矩阵是对称矩阵那么这个模板也称为卷积模板,如果不对称则是一般的运算模板。我们通常使用的模板一般都是卷积模板。如边缘提取中的Sobel算子模板。
           
图 4-a Mx算子模板                         图4-bMy算子模板
       模板运算一般操作过程分为以下三个步骤:
       1)定"锚点 ":就是处理之后的结果值的保存位置,该位置称为"锚点 ",有时候也不在中心。            
       2)对位相乘:模板和原图像的待处理区域,进行对位相乘运算           
       3)求和:将步骤2中模板区域内运算结果进行求和,将求和的结果置于"锚点 "

     4.形态学处理
     形态学处理是二值图像处理中的经典处理手段,主要有膨胀处理和腐蚀处理。也包含一些其他操作如 二值开闭运算、骨架抽取、极限腐蚀、击中击不中变换、形态学梯度、Top-hat变换、颗粒分析、流域变换等。
    膨胀和腐蚀操作主要的功能有:1)消除杂波,噪声信息  2)填充图像内部的"孔洞"  3)平滑边缘毛刺
    膨胀和腐蚀具有类似的数学模型,这里就一起介绍了,简单来说膨胀就是取最大值,腐蚀操作是取最小值。
    膨胀操作的数学表达式为:
                                                                      
    腐蚀操作的数学表达式为:

    膨胀操作和腐蚀操作一般的处理过程如下:
    1)按照选定的处理核(NxN,一般N为奇数)与源图像的区域进行逐个“锚点”配对
    2)将配对的处理邻域信息进行相应操作,膨胀操作就取最大值,腐蚀操作就取最小值
    3)求的结果作为源图像中配对区域的数值。
                         
                                                          图a 原图                                                                图b 膨胀处理图                                                           图c 腐蚀处理
 

FPGA的图像处理算法

阅读数 1961

图像基本运算

阅读数 1566

没有更多推荐了,返回首页