2019-09-04 21:38:30 lengo 阅读数 429
  • 图解Java数据结构和算法

    1.算法是程序的灵魂,优秀的程序在对海量数据处理时,依然保持高速计算,就需要高效的数据结构和算法支撑。2.网上数据结构和算法的课程不少,但存在两个问题: 1)授课方式单一,大多是照着代码念一遍,数据结构和算法本身就比较难理解,对基础好的学员来说,还好一点,对基础不好的学生来说,基本上就是听天书了 2)说是讲数据结构和算法,但大多是挂羊头卖狗肉,算法讲的很少。 本课程针对上述问题,有针对性的进行了升级  3)授课方式采用图解+算法游戏的方式,让课程生动有趣好理解 4)系统全面的讲解了数据结构和算法, 除常用数据结构和算法外,还包括程序员常用10大算法:二分查找算法(非递归)、分治算法、动态规划算法、KMP算法、贪心算法、普里姆算法、克鲁斯卡尔算法、迪杰斯特拉算法、弗洛伊德算法、马踏棋盘算法。可以解决面试遇到的最短路径、最小生成树、最小连通图、动态规划等问题及衍生出的面试题,让你秒杀其他面试小伙伴 3.如果你不想永远都是代码工人,就需要花时间来研究下数据结构和算法。教程内容: 本教程是使用Java来讲解数据结构和算法,考虑到数据结构和算法较难,授课采用图解加算法游戏的方式。内容包括: 稀疏数组、单向队列、环形队列、单向链表、双向链表、环形链表、约瑟夫问题、栈、前缀、中缀、后缀表达式、中缀表达式转换为后缀表达式、递归与回溯、迷宫问题、八皇后问题、算法的时间复杂度、冒泡排序、选择排序、插入排序、快速排序、归并排序、希尔排序、基数排序(桶排序)、堆排序、排序速度分析、二分查找、插值查找、斐波那契查找、散列、哈希表、二叉树、二叉树与数组转换、二叉排序树(BST)、AVL树、线索二叉树、赫夫曼树、赫夫曼编码、多路查找树(B树B+树和B*树)、图、图的DFS算法和BFS、程序员常用10大算法、二分查找算法(非递归)、分治算法、动态规划算法、KMP算法、贪心算法、普里姆算法、克鲁斯卡尔算法、迪杰斯特拉算法、弗洛伊德算法马踏棋盘算法。 学习目标:通过学习,学员能掌握主流数据结构和算法的实现机制,开阔编程思路,提高优化程序的能力。

    3197 人正在学习 去看看 佟刚
clc;
clear all;
close all;
%提取连通分量测试图像,用来检测食物中的外来物
I=im2double(imread('D:\Gray Files\9-18a.tif'));
%获得图像大小
[M,N]=size(I);
%存放腐蚀后的图像
%设定提取门限,根据经验设定
th=0.808;
%将原图像根据上述门限进行二值处理,大于等于门限为1,小于为0
ind=find(I>=th);
I(ind)=1;
ind=find(I<th);
I(ind)=0;
%获得值为1的x,y坐标
[rows,cols]=find(I==1);
%将x,y坐标点组合成下标矩阵
index=cat(2,rows,cols);
%5*5结构元素
n=5;
B=ones(n,n);
n_l=floor(n/2);
%对边界图进行扩充,四周各加2行、2列0(与结构元素的大小相对应),目的是为了处理边界点
I_pad=padarray(I,[n_l,n_l]);
%将下标矩阵加2
index=index+2;
%保存所有连通对象集
Objs={};
%设定递归上限
set(0,'RecursionLimit',10000);
%递归寻找连通对象
while 1
    %取出下标矩阵中的第一个值
    if isempty(index)
        break;
    end
    %取出下标矩阵中的第一个对象
    p=index(1,:);
    A=FindConnectedPoint(p,I_pad,index,n_l);  
    %将边界线对象保存至对象集
    Objs=cat(1,Objs,A{1,1}-n_l);
    index=A{1,2}; 
    I_pad=A{1,3};        
end
%显示连通对象
J=zeros(M,N);
if ~isempty(Objs)
    for i=1:size(Objs,1)
        Obj=Objs{i,1};
        for j=1:size(Obj,1)
            J(Obj(j,1),Obj(j,2))=1;
        end
    end
end
imshow(J)

FindConnectedPoint函数如下:

function R=FindConnectedPoint(p,Beta_pad,ind,n_l)
    %保存边界坐标对象
    Obj=[];
    %以p为中心点,从边界图中取出3*3大小的块区域
    Block=Beta_pad(p(1,1)-n_l:p(1,1)+n_l,p(1,2)-n_l:p(1,2)+n_l);
    Obj=p;
    %将图像中的p点置零
    Beta_pad(p(1,1),p(1,2))=0;
    %将块区域中的p点置零
    Block(n_l+1,n_l+1)=0;
    A=cell(1,3);
    %将p点从下标矩阵中删除
    for j=1:size(ind,1)
        if ind(j,:)==p
            ind(j,:)=[];
            break;
        end
    end
    %寻找块区域中为1的点的下标
    [rows,cols]=find(Block==1);
    ind_sub=cat(2,rows,cols);
    if ~isempty(ind_sub)
        %确定块中数值为1的点的坐标
        for i=1:size(ind_sub,1) 
            p_next=[];
            if ind_sub(i,1)<=n_l+1
                p_next(1,1)=p(1,1)-abs(n_l+1-ind_sub(i,1));
                if ind_sub(i,2)<=n_l+1                    
                    p_next(1,2)=p(1,2)-abs(n_l+1-ind_sub(i,2));
                else
                    p_next(1,2)=p(1,2)+abs(n_l+1-ind_sub(i,2));                    
                end
            else
                p_next(1,1)=p(1,1)+abs(n_l+1-ind_sub(i,1));
                if ind_sub(i,2)<=n_l+1                    
                    p_next(1,2)=p(1,2)-abs(n_l+1-ind_sub(i,2));
                else
                    p_next(1,2)=p(1,2)+abs(n_l+1-ind_sub(i,2));                    
                end                
            end
            if Beta_pad(p_next(1,1),p_next(1,2))~=0                        
                A=FindConnectedPoint(p_next,Beta_pad,ind,n_l);
                Obj=cat(1,A{1,1},Obj);   
            end                       
            %更新下标矩阵
            ind=A{1,2};
            Beta_pad=A{1,3};
        end
    end
    %返回结果
    R={Obj,ind,Beta_pad};
end

 

2014-01-26 18:01:12 jia20003 阅读数 8005
  • 图解Java数据结构和算法

    1.算法是程序的灵魂,优秀的程序在对海量数据处理时,依然保持高速计算,就需要高效的数据结构和算法支撑。2.网上数据结构和算法的课程不少,但存在两个问题: 1)授课方式单一,大多是照着代码念一遍,数据结构和算法本身就比较难理解,对基础好的学员来说,还好一点,对基础不好的学生来说,基本上就是听天书了 2)说是讲数据结构和算法,但大多是挂羊头卖狗肉,算法讲的很少。 本课程针对上述问题,有针对性的进行了升级  3)授课方式采用图解+算法游戏的方式,让课程生动有趣好理解 4)系统全面的讲解了数据结构和算法, 除常用数据结构和算法外,还包括程序员常用10大算法:二分查找算法(非递归)、分治算法、动态规划算法、KMP算法、贪心算法、普里姆算法、克鲁斯卡尔算法、迪杰斯特拉算法、弗洛伊德算法、马踏棋盘算法。可以解决面试遇到的最短路径、最小生成树、最小连通图、动态规划等问题及衍生出的面试题,让你秒杀其他面试小伙伴 3.如果你不想永远都是代码工人,就需要花时间来研究下数据结构和算法。教程内容: 本教程是使用Java来讲解数据结构和算法,考虑到数据结构和算法较难,授课采用图解加算法游戏的方式。内容包括: 稀疏数组、单向队列、环形队列、单向链表、双向链表、环形链表、约瑟夫问题、栈、前缀、中缀、后缀表达式、中缀表达式转换为后缀表达式、递归与回溯、迷宫问题、八皇后问题、算法的时间复杂度、冒泡排序、选择排序、插入排序、快速排序、归并排序、希尔排序、基数排序(桶排序)、堆排序、排序速度分析、二分查找、插值查找、斐波那契查找、散列、哈希表、二叉树、二叉树与数组转换、二叉排序树(BST)、AVL树、线索二叉树、赫夫曼树、赫夫曼编码、多路查找树(B树B+树和B*树)、图、图的DFS算法和BFS、程序员常用10大算法、二分查找算法(非递归)、分治算法、动态规划算法、KMP算法、贪心算法、普里姆算法、克鲁斯卡尔算法、迪杰斯特拉算法、弗洛伊德算法马踏棋盘算法。 学习目标:通过学习,学员能掌握主流数据结构和算法的实现机制,开阔编程思路,提高优化程序的能力。

    3197 人正在学习 去看看 佟刚

图像处理之计算连通区域的角度方向

一:基本原理

基于空间Moment算法在图像处理与分析中寻找连通区域计算连通区域的中心与角度方

Moment的一阶可以用来计算区域的中心质点,二阶可以用来证明图像的几个不变性

如旋转不变行,放缩不变性等。基于Moment的二阶计算结果,根据如下公式:


可以得到区域的方向角度。

二:算法流程

1.      读入图像数据

2.      根据连通组件标记算法得到区域

3.      根据中心化Moment算法计算角度

4.      根据中心离心值画出渲染黄色线条

三:算法演示效果


四:算法主要源代码

package com.gloomyfish.image.moments;

import java.awt.image.BufferedImage;

import com.gloomyfish.filter.study.AbstractBufferedImageOp;
import com.gloomyfish.rice.analysis.FastConnectedComponentLabelAlg;

public class DirectionRegionMoments extends AbstractBufferedImageOp {

	@Override
	public BufferedImage filter(BufferedImage src, BufferedImage dest) {
		int width = src.getWidth();
        int height = src.getHeight();

        if ( dest == null )
        	dest = createCompatibleDestImage( src, null );

        // first step - make it as binary image output pixel
        int[] inPixels = new int[width*height];
        int[] outPixels = new int[width*height];
        getRGB( src, 0, 0, width, height, inPixels );
        int index = 0;
        for(int row=0; row<height; row++) {
        	int tr = 0;
        	for(int col=0; col<width; col++) {
        		index = row * width + col;
                tr = (inPixels[index] >> 16) & 0xff;
                if(tr > 127)
                {
                	 outPixels[index] = 1;
                }
                else
                {
                	outPixels[index] = 0;
                }
        	}
        }
        
        // second step, connected component labeling algorithm
        FastConnectedComponentLabelAlg ccLabelAlg = new FastConnectedComponentLabelAlg();
        ccLabelAlg.setBgColor(0);
        int[] labels = ccLabelAlg.doLabel(outPixels, width, height);
        int max = 0;
        for(int i=0; i<labels.length; i++)
        {
        	if(max < labels[i])
        	{
        		System.out.println("Label Index = " + labels[i]);
        		max = labels[i];
        	}
        }
        
        // third step, calculate the orientation of the region
        int[] input = new int[labels.length];
        GeometricMomentsAlg momentsAlg = new GeometricMomentsAlg();
        momentsAlg.setBACKGROUND(0);
        double[][] labelCenterPos = new double[max][2];
        double[][] centerAngles = new double[max][3];
        for(int i=1; i<=max; i++)
        {
        	int numberOfLabel = 0;
        	for(int p=0; p<input.length; p++)
        	{
        		if(labels[p] == i)
        		{
        			input[p] = labels[p];  
        			numberOfLabel++;
        		}
        		else
        		{
        			input[p] = 0;
        		}
        	}
        	labelCenterPos[i-1] = momentsAlg.getGeometricCenterCoordinate(input, width, height);
        	double m11 = momentsAlg.centralMoments(input, width, height, 1, 1);
        	double m02 = momentsAlg.centralMoments(input, width, height, 0, 2);
        	double m20 = momentsAlg.centralMoments(input, width, height, 2, 0);
        	double m112 = m11 * m11;
        	double dd = Math.pow((m20-m02), 2);
        	double sum1 = Math.sqrt(dd + 4*m112);
        	double sum2 = m02 + m20;
        	double a1 = sum2 + sum1;
        	double a2 = sum2 - sum1;
        	// double ecc = a1 / a2;
        	
        	double ra = Math.sqrt((2*a1)/Math.abs(numberOfLabel));
        	double rb = Math.sqrt((2*a2)/Math.abs(numberOfLabel));
        	double angle = Math.atan((2*m11)/(m20 - m02))/2.0;
        	centerAngles[i-1][0] = angle;
        	centerAngles[i-1][1] = ra;
        	centerAngles[i-1][2] = rb;
        }
        
        
        // render the angle/orientation info for each region
        // render the each connected component center position
        for(int row=0; row<height; row++) {
        	for(int col=0; col<width; col++) {
        		index = row * width + col;
        		if(labels[index] == 0)
        		{
        			outPixels[index] = (255 << 24) | (0 << 16) | (0 << 8) | 0; // make it as black for background
        		}
        		else
        		{
        			outPixels[index] = (255 << 24) | (0 << 16) | (0 << 8) | 100; // make it as blue for each region area
        		}
        	}
        }
        
        int labelCount = centerAngles.length;
        for(int i=0; i<labelCount; i++)
        {
        	System.out.println("Region " + i + "'s angle = " + centerAngles[i][0]);
        	System.out.println("Region " + i + " ra = " + centerAngles[i][1]);
        	System.out.println("Region " + i + " rb = " + centerAngles[i][2]);
        	double sin = Math.sin(centerAngles[i][0]);
        	double cos = Math.cos(centerAngles[i][0]);
        	System.out.println("sin = " + sin);
        	System.out.println("cos = " + cos);
        	System.out.println();
        	int crow = (int)labelCenterPos[i][0];
        	int ccol = (int)labelCenterPos[i][1];
        	int radius = (int)centerAngles[i][1]; // ra
        	for(int j=0; j<radius; j++)
        	{
        		int drow = (int)(crow - j * sin); // it is trick, display correct angle as you see!!!
        		int dcol = (int)(ccol + j * cos);
        		if(drow >= height) continue;
        		if(dcol >= width) continue;
        		index = drow * width + dcol;
            	outPixels[index] = (255 << 24) | (255 << 16) | (255 << 8) | 0; 
        	}
        }
        
        // make it as white color for each center position
        for(int i=0; i<max; i++)
        {
        	int crow = (int)labelCenterPos[i][0];
        	int ccol = (int)labelCenterPos[i][1];
        	index = crow * width + ccol;
        	outPixels[index] = (255 << 24) | (255 << 16) | (255 << 8) | 255; 
        }
        
        setRGB( dest, 0, 0, width, height, outPixels );
		return dest;
	}

}
用到的其它JAVA类代码请参见这里:

http://blog.csdn.net/jia20003/article/details/17596645

2018-07-24 10:01:29 DL960722 阅读数 1856
  • 图解Java数据结构和算法

    1.算法是程序的灵魂,优秀的程序在对海量数据处理时,依然保持高速计算,就需要高效的数据结构和算法支撑。2.网上数据结构和算法的课程不少,但存在两个问题: 1)授课方式单一,大多是照着代码念一遍,数据结构和算法本身就比较难理解,对基础好的学员来说,还好一点,对基础不好的学生来说,基本上就是听天书了 2)说是讲数据结构和算法,但大多是挂羊头卖狗肉,算法讲的很少。 本课程针对上述问题,有针对性的进行了升级  3)授课方式采用图解+算法游戏的方式,让课程生动有趣好理解 4)系统全面的讲解了数据结构和算法, 除常用数据结构和算法外,还包括程序员常用10大算法:二分查找算法(非递归)、分治算法、动态规划算法、KMP算法、贪心算法、普里姆算法、克鲁斯卡尔算法、迪杰斯特拉算法、弗洛伊德算法、马踏棋盘算法。可以解决面试遇到的最短路径、最小生成树、最小连通图、动态规划等问题及衍生出的面试题,让你秒杀其他面试小伙伴 3.如果你不想永远都是代码工人,就需要花时间来研究下数据结构和算法。教程内容: 本教程是使用Java来讲解数据结构和算法,考虑到数据结构和算法较难,授课采用图解加算法游戏的方式。内容包括: 稀疏数组、单向队列、环形队列、单向链表、双向链表、环形链表、约瑟夫问题、栈、前缀、中缀、后缀表达式、中缀表达式转换为后缀表达式、递归与回溯、迷宫问题、八皇后问题、算法的时间复杂度、冒泡排序、选择排序、插入排序、快速排序、归并排序、希尔排序、基数排序(桶排序)、堆排序、排序速度分析、二分查找、插值查找、斐波那契查找、散列、哈希表、二叉树、二叉树与数组转换、二叉排序树(BST)、AVL树、线索二叉树、赫夫曼树、赫夫曼编码、多路查找树(B树B+树和B*树)、图、图的DFS算法和BFS、程序员常用10大算法、二分查找算法(非递归)、分治算法、动态规划算法、KMP算法、贪心算法、普里姆算法、克鲁斯卡尔算法、迪杰斯特拉算法、弗洛伊德算法马踏棋盘算法。 学习目标:通过学习,学员能掌握主流数据结构和算法的实现机制,开阔编程思路,提高优化程序的能力。

    3197 人正在学习 去看看 佟刚

      图像是由像素点组成的矩阵,矩阵的每个点记录着图像的RGB值。数字图像处理即根据用户需求,使用计算机技术对图像进行处理得到所需效果。

1.采样

      我们获取到的图像一般为模拟图像,要让计算机进行处理需将其数字化,采样的作用就是将模拟图像转变为数字图像。一般来说,采样间隔越大,所得图像像素数越少,空间分辨率越低,质量差,严重时出现马赛克效应;采样间隔越小,所得图像像素数越多,空间分辨率越高,图像质量好,但数据量大。

2.量化

       模拟图像经过采样后,在时间和空间上离散化为像素,但采样所得的像素值(即灰度值)仍是连续量,把采样后所得的各像素的灰度值从模拟量到离散量的转换称为图像灰度的量化。量化等级越多,所得图像层次越丰富,灰度分辨率高,图像质量好,但数据量大;量化等级越少,图像层次欠丰富,灰度分辨率低,会出现假轮廓现象,图像质量变差,但数据量小。

一般,当限定数字图像的大小时, 为了得到质量较好的图像可采用如下原则:

   (1) 对缓变的图像, 应该细量化, 粗采样, 以避免假轮廓。

   (2) 对细节丰富的图像,应细采样,粗量化, 以避免模糊(混叠)。

3.邻域

图像邻域即相邻像素关系,有4-邻域、8-邻域、D邻域

(1)4-邻域

4-邻域即像素点的上下左右四个点构成的邻域。设p(i,j),则p(i-1,j)、p(i+1,j)、p(i,j+1)、p(i,j-1)为其4-领域点。

(2)8-邻域

8-邻域即像素点周围一圈的八个点构成的邻域。设p(i,j),则p(i-1,j)、p(i+1,j)、p(i,j+1)、p(i,j-1)、p(i+1,j+1)、p(i-1,j+1),p(i-1,j-1),p(i-1,j-1)为其8-邻域点。

(3)D邻域

D邻域及像素点对角上的点。设p(i,j),则p(i+1,j+1)、p(i-1,j+1),p(i-1,j-1),p(i-1,j-1)为其D邻域点。

4.连通性

两像素连通的必要条件:1)两像素位置是否相邻;2)两像素灰度值是否满足特定的相似性准则

(1)4连通:两个像素p和q,如果p在q的4邻域中,称这两个像素是4连通

(2)8连通:两个像素p和q,如果p在q的8邻域中,称这两个像素是8连通

(3)m连通:1)两个像素p和q,p在q的4邻域内,或者p在q的D邻域内   2)且p和q的4邻域的交集为空,即m连通是4连通和D连通的混合(mixture)连通,(特别注意第二个条件!)

 

2015-07-24 09:57:36 mao0514 阅读数 1676
  • 图解Java数据结构和算法

    1.算法是程序的灵魂,优秀的程序在对海量数据处理时,依然保持高速计算,就需要高效的数据结构和算法支撑。2.网上数据结构和算法的课程不少,但存在两个问题: 1)授课方式单一,大多是照着代码念一遍,数据结构和算法本身就比较难理解,对基础好的学员来说,还好一点,对基础不好的学生来说,基本上就是听天书了 2)说是讲数据结构和算法,但大多是挂羊头卖狗肉,算法讲的很少。 本课程针对上述问题,有针对性的进行了升级  3)授课方式采用图解+算法游戏的方式,让课程生动有趣好理解 4)系统全面的讲解了数据结构和算法, 除常用数据结构和算法外,还包括程序员常用10大算法:二分查找算法(非递归)、分治算法、动态规划算法、KMP算法、贪心算法、普里姆算法、克鲁斯卡尔算法、迪杰斯特拉算法、弗洛伊德算法、马踏棋盘算法。可以解决面试遇到的最短路径、最小生成树、最小连通图、动态规划等问题及衍生出的面试题,让你秒杀其他面试小伙伴 3.如果你不想永远都是代码工人,就需要花时间来研究下数据结构和算法。教程内容: 本教程是使用Java来讲解数据结构和算法,考虑到数据结构和算法较难,授课采用图解加算法游戏的方式。内容包括: 稀疏数组、单向队列、环形队列、单向链表、双向链表、环形链表、约瑟夫问题、栈、前缀、中缀、后缀表达式、中缀表达式转换为后缀表达式、递归与回溯、迷宫问题、八皇后问题、算法的时间复杂度、冒泡排序、选择排序、插入排序、快速排序、归并排序、希尔排序、基数排序(桶排序)、堆排序、排序速度分析、二分查找、插值查找、斐波那契查找、散列、哈希表、二叉树、二叉树与数组转换、二叉排序树(BST)、AVL树、线索二叉树、赫夫曼树、赫夫曼编码、多路查找树(B树B+树和B*树)、图、图的DFS算法和BFS、程序员常用10大算法、二分查找算法(非递归)、分治算法、动态规划算法、KMP算法、贪心算法、普里姆算法、克鲁斯卡尔算法、迪杰斯特拉算法、弗洛伊德算法马踏棋盘算法。 学习目标:通过学习,学员能掌握主流数据结构和算法的实现机制,开阔编程思路,提高优化程序的能力。

    3197 人正在学习 去看看 佟刚

连接组件标记算法(connected component labeling algorithm)是图像分析中最常用的算法之一,

算法的实质是扫描一幅图像的每个像素,对于像素值相同的分为相同的组(group),最终得到

图像中所有的像素连通组件。扫描的方式可以是从上到下,从左到右,对于一幅有N个像

素的图像来说,最大连通组件个数为N/2。扫描是基于每个像素单位,对于二值图像而言,

连通组件集合可以是V={1}或者V={0}, 取决于前景色与背景色的不同。对于灰度图像来说,

连图组件像素集合可能是一系列在0 ~ 255之间的灰度值。

 

算法流程如下:

1.      首先扫描当前像素相邻的八邻域像素值,发现连通像素加以标记。

2.      完全扫描所有像素点之后,根据标记将所有连通组件合并。

 

算法实现Class文件解释:

AbstractConnectedComponentLabel一个抽象的Class定义了抽象方法doConntectedLabel()

同时完成了一些公共方法

ConnectedComponentLabelAlgOne一个容易读懂的连接组件算法完成,没有任何优化,

继承上面的自抽象类

ConnectedComponentLabelAlgTwo一个快速的连接组件算法,基于算法优化,取当前像素

的四邻域完成扫描与标记合并。

 

LabelPixelInfo是两个数据结构,用来存储算法计算过程中的中间变量。

 

ImageLabelFilter用来测试算法的驱动类,ImageAnalysisUI是现实测试结果的UI

 

算法运行结果:

 

根据标记的索引将组件着色。


定义数据结构的代码如下:

  1. public class Label {  
  2.       
  3.     private int index;  
  4.     private Label root;  
  5.       
  6.     public Label(int index) {  
  7.         this.index = index;  
  8.         this.root = this;  
  9.     }  
  10.       
  11.     public Label getRoot() {  
  12.         if(this.root != this) {  
  13.             this.root = this.root.getRoot();  
  14.         }  
  15.         return root;  
  16.     }  
  17.   
  18.     public int getIndex() {  
  19.         return index;  
  20.     }  
  21.   
  22.     public void setIndex(int index) {  
  23.         this.index = index;  
  24.     }  
  25.   
  26.     public void setRoot(Label root) {  
  27.         this.root = root;  
  28.     }  
  29. }  

Pixelnfo的代码如下:

  1. package com.gloomyfish.image.analysis;  
  2.   
  3. public class PixelInfo {  
  4.     private int value; // pixel value  
  5.     private int xp;  
  6.     private int yp;  
  7.       
  8.     public PixelInfo(int pixelValue, int yp, int xp) {  
  9.         this.value = pixelValue;  
  10.         this.yp = yp;  
  11.         this.xp = xp;  
  12.     }  
  13.       
  14.     public int getValue() {  
  15.         return value;  
  16.     }  
  17.     public void setValue(int value) {  
  18.         this.value = value;  
  19.     }  
  20.     public int getXp() {  
  21.         return xp;  
  22.     }  
  23.     public void setXp(int xp) {  
  24.         this.xp = xp;  
  25.     }  
  26.     public int getYp() {  
  27.         return yp;  
  28.     }  
  29.     public void setYp(int yp) {  
  30.         this.yp = yp;  
  31.     }  
  32. }  
抽象的组件连通标记算法Class如下:

  1. public abstract class AbstractConnectedComponentLabel {  
  2.       
  3.     protected int width;  
  4.     protected int height;  
  5.     protected Color fgColor;  
  6.     protected int[] inPixels;  
  7.     protected int[][] chessborad;  
  8.     protected Map<Integer, Integer> neighbourMap;  
  9.       
  10.     public int getWidth() {  
  11.         return width;  
  12.     }  
  13.   
  14.     public void setWidth(int width) {  
  15.         this.width = width;  
  16.     }  
  17.   
  18.     public int getHeight() {  
  19.         return height;  
  20.     }  
  21.   
  22.     public void setHeight(int height) {  
  23.         this.height = height;  
  24.     }  
  25.       
  26.     public abstract Map<Integer, List<PixelInfo>> doConntectedLabel();  
  27.   
  28.     public boolean isForeGround(int tr, int tg, int tb) {  
  29.         if(tr == fgColor.getRed() && tg == fgColor.getGreen() && tb == fgColor.getBlue()) {  
  30.             return true;  
  31.         } else {  
  32.             return false;  
  33.         }  
  34.           
  35.     }  
  36.   
  37. }  
实现抽象类的算法one的代码如下:

  1. import java.awt.Color;  
  2. import java.util.ArrayList;  
  3. import java.util.HashMap;  
  4. import java.util.List;  
  5. import java.util.Map;  
  6.   
  7. public class ConnectedComponentLabelAlgOne extends AbstractConnectedComponentLabel {  
  8.   
  9.     public ConnectedComponentLabelAlgOne(Color fgColor, int[] srcPixel, int width, int height) {  
  10.         this.fgColor = fgColor;  
  11.         this.width = width;  
  12.         this.height = height;  
  13.         this.inPixels = srcPixel;  
  14.         this.chessborad = new int[height][width];  
  15.         for(int i=0; i<height; i++) {  
  16.             for(int j=0; j<width; j++) {  
  17.                 chessborad[i][j] = 0;  
  18.             }  
  19.         }  
  20.         this.neighbourMap = new HashMap<Integer, Integer>();   
  21.     }  
  22.       
  23.     // assume the input image data is binary image.  
  24.     public Map<Integer, List<PixelInfo>> doConntectedLabel() {  
  25.         System.out.println("start to do connected component labeling algorithm");  
  26.         int index = 0;  
  27.         int labelCount = 0;  
  28.         Label currentLabel = new Label(0);  
  29.         HashMap<Integer, Label> allLabels = new HashMap<Integer, Label>();  
  30.         for(int row=0; row<height; row++) {  
  31.             int ta = 0, tr = 0, tg = 0, tb = 0;  
  32.             for(int col=0; col<width; col++) {  
  33.                 index = row * width + col;  
  34.                 ta = (inPixels[index] >> 24) & 0xff;  
  35.                 tr = (inPixels[index] >> 16) & 0xff;  
  36.                 tg = (inPixels[index] >> 8) & 0xff;  
  37.                 tb = inPixels[index] & 0xff;  
  38.                 if(isForeGround(tr, tg, tb)) {  
  39.                     getNeighboringLabels(row, col);  
  40.                     if(neighbourMap.size() == 0) {  
  41.                         currentLabel.setIndex(++labelCount);  
  42.                         allLabels.put(labelCount,new Label(labelCount));  
  43.   
  44.                     } else {  
  45.                         for(Integer pixelLabel : neighbourMap.keySet().toArray(new Integer[0])) {  
  46.                             currentLabel.setIndex(pixelLabel);  
  47.                             break;  
  48.                         }  
  49.                         mergeLabels(currentLabel.getIndex(), neighbourMap, allLabels);  
  50.                     }  
  51.                     chessborad[row][col] = currentLabel.getIndex();  
  52.                 }  
  53.             }  
  54.         }  
  55.           
  56.         Map<Integer, List<PixelInfo>> connectedLabels = consolidateAllLabels(allLabels);  
  57.         return connectedLabels;  
  58.     }  
  59.       
  60.     private Map<Integer, List<PixelInfo>> consolidateAllLabels(HashMap<Integer, Label> allLabels) {  
  61.         Map<Integer, List<PixelInfo>> patterns = new HashMap<Integer, List<PixelInfo>>();  
  62.         int patternNumber;  
  63.         List<PixelInfo> shape;  
  64.         for (int i = 0; i < this.height; i++)  
  65.         {  
  66.             for (int j = 0; j < this.width; j++)  
  67.             {  
  68.                 patternNumber = chessborad[i][j];  
  69.                 if (patternNumber != 0)  
  70.                 {  
  71.                     patternNumber = allLabels.get(patternNumber).getRoot().getIndex();  
  72.                     if (!patterns.containsKey(patternNumber))  
  73.                     {  
  74.                         shape = new ArrayList<PixelInfo>();  
  75.                         shape.add(new PixelInfo(Color.BLUE.getRGB(), i, j));  
  76.                     }  
  77.                     else  
  78.                     {  
  79.                         shape = patterns.get(patternNumber);  
  80.                         shape.add(new PixelInfo(Color.BLUE.getRGB(), i, j));  
  81.                     }  
  82.                     patterns.put(patternNumber, shape);  
  83.                 }  
  84.             }  
  85.         }  
  86.         return patterns;  
  87.     }  
  88.   
  89.     private void mergeLabels(int index, Map<Integer, Integer> neighbourMap,  
  90.             HashMap<Integer, Label> allLabels) {  
  91.         Label root = allLabels.get(index).getRoot();  
  92.         Label neighbour;  
  93.         for(Integer key : neighbourMap.keySet().toArray(new Integer[0])) {  
  94.              if (key != index)  
  95.              {  
  96.                  neighbour = allLabels.get(key);  
  97.                  if(neighbour.getRoot() != root) {  
  98.                      neighbour.setRoot(neighbour.getRoot());// thanks zhen712,  
  99.                  }  
  100.              }  
  101.         }  
  102.           
  103.     }  
  104.   
  105.     /** 
  106.      * get eight neighborhood pixels 
  107.      *  
  108.      * @param row 
  109.      * @param col 
  110.      * @return 
  111.      */  
  112.     public  void getNeighboringLabels(int row, int col) {  
  113.         neighbourMap.clear();  
  114.         for(int i=-1; i<=1; i++) {  
  115.             int yp = row + i;  
  116.             if(yp >=0 && yp < this.height) {  
  117.                 for(int j=-1; j<=1; j++) {  
  118.                     if(i == 0 && j==0continue// ignore/skip center pixel/itself  
  119.                     int xp = col + j;  
  120.                     if(xp >=0 && xp < this.width) {  
  121.                         if(chessborad[yp][xp] != 0) {  
  122.                             if(!neighbourMap.containsKey(chessborad[yp][xp])) {  
  123.                                 neighbourMap.put(chessborad[yp][xp],0);  
  124.                             }  
  125.                         }  
  126.                     }  
  127.                 }  
  128.             }  
  129.         }  
  130.     }  
  131. }  
2018-02-23 21:22:51 revitalise 阅读数 1686
  • 图解Java数据结构和算法

    1.算法是程序的灵魂,优秀的程序在对海量数据处理时,依然保持高速计算,就需要高效的数据结构和算法支撑。2.网上数据结构和算法的课程不少,但存在两个问题: 1)授课方式单一,大多是照着代码念一遍,数据结构和算法本身就比较难理解,对基础好的学员来说,还好一点,对基础不好的学生来说,基本上就是听天书了 2)说是讲数据结构和算法,但大多是挂羊头卖狗肉,算法讲的很少。 本课程针对上述问题,有针对性的进行了升级  3)授课方式采用图解+算法游戏的方式,让课程生动有趣好理解 4)系统全面的讲解了数据结构和算法, 除常用数据结构和算法外,还包括程序员常用10大算法:二分查找算法(非递归)、分治算法、动态规划算法、KMP算法、贪心算法、普里姆算法、克鲁斯卡尔算法、迪杰斯特拉算法、弗洛伊德算法、马踏棋盘算法。可以解决面试遇到的最短路径、最小生成树、最小连通图、动态规划等问题及衍生出的面试题,让你秒杀其他面试小伙伴 3.如果你不想永远都是代码工人,就需要花时间来研究下数据结构和算法。教程内容: 本教程是使用Java来讲解数据结构和算法,考虑到数据结构和算法较难,授课采用图解加算法游戏的方式。内容包括: 稀疏数组、单向队列、环形队列、单向链表、双向链表、环形链表、约瑟夫问题、栈、前缀、中缀、后缀表达式、中缀表达式转换为后缀表达式、递归与回溯、迷宫问题、八皇后问题、算法的时间复杂度、冒泡排序、选择排序、插入排序、快速排序、归并排序、希尔排序、基数排序(桶排序)、堆排序、排序速度分析、二分查找、插值查找、斐波那契查找、散列、哈希表、二叉树、二叉树与数组转换、二叉排序树(BST)、AVL树、线索二叉树、赫夫曼树、赫夫曼编码、多路查找树(B树B+树和B*树)、图、图的DFS算法和BFS、程序员常用10大算法、二分查找算法(非递归)、分治算法、动态规划算法、KMP算法、贪心算法、普里姆算法、克鲁斯卡尔算法、迪杰斯特拉算法、弗洛伊德算法马踏棋盘算法。 学习目标:通过学习,学员能掌握主流数据结构和算法的实现机制,开阔编程思路,提高优化程序的能力。

    3197 人正在学习 去看看 佟刚

在此用矩形连通域为例

当获取车牌位置信息时,连通域的长宽比是一种非常有效的辅助定位方法。

大致步骤:

1.输入图像获取灰度图像。

2.选取合适的阈值将灰度图像转化为二值图像。

3.对二值图像进行形态学处理,主要任务是去除连通域面积较小的区域以及降低筛选难度。

4.利用bwlabel()函数对连通区域进行标记

5.得到连通域的长宽比


matlab实现程序:

clear all;close all;clc
I= imread('F:\matlab\MATLAB上机操作\源代码\Fig0903(a)(utk).tif');
I = rgb2gray(RGB);
threshold = graythresh(I);
bw = bwareaopen(bw,50);%去除连通域面积小于50的区域(连通域面积与对象的像素数目不一定相等)
se = strel('disk',2);
bw = imclose(bw,se);%闭运算
bw = imfill(bw,'holes');%填充
ed=edge(bw);
L = bwlabel(bw);%标记连通域
L1 = bwlabel(ed);
p=zeros(1,max(L1(:)));
for i=1:max(L(:))%得到连通域的长宽比
p(i)=sum(ed(L==i));
[y,x]=find(L==i);
x0=min(x(:));
x1=max(x(:));
y0=min(y(:));
y1=max(y(:));
bl=(x1-x0)/(y1-y0);
disp(bl)
end


图像填充imfill()

bw2=imfill(bw)该函数对二值图像进行填充操作,对于二维图像允许通过鼠标选择填充的点。

[bw2,locations]=imfill(bw)  locations包含交互式选择时的点坐标。

bw2=imfill(bw,’holes’)通过参数holes可以填充二值图像的空洞。

连通域标记bwlabel()

L=bwlabel(bw,n)该函数先对二值图像的连通区域进行标记,参数n为联通类型,可取值48,默认为8,即为8连通,函数返回值为标记矩阵和原来的二值图像有相同的大小

[l,num]=bwlabel(bw,n)  num为连通域的数目。

Bwlabel()返回的标记矩阵可以通过函数label2rgb()进行显示。


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