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

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

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

一:基本原理

基于空间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

相关文章
技术好文共享:辅助角公式的几何意义
技术好文共享:辅助角公式的几何意义
|
22天前
|
算法 计算机视觉
图像处理之计算二值连通区域的质心
图像处理之计算二值连通区域的质心
13 0
|
1月前
[C++&OpenCv] 两点距离、三点角度的计算
[C++&OpenCv] 两点距离、三点角度的计算
82 0
|
8月前
3D孪生场景搭建:模型区域摆放
NSDT 3D孪生场景编辑器区域绘制功能详解。
143 0
3D孪生场景搭建:模型区域摆放
三维之外的更高维度,数学家发现了无限可能的黑洞形状
三维之外的更高维度,数学家发现了无限可能的黑洞形状
110 0
【双目视觉】 理想条件下计算物体距离
【双目视觉】 理想条件下计算物体距离
51 0
|
传感器 机器学习/深度学习 编解码
3D多目标跟踪新思路!基于多传感器融合的加权几何距离关联方法
在自动驾驶领域,3D多目标跟踪(MOT)作为整个感知系统中的关键任务之一发挥着重要作用,它确保了车辆导航和运动规划的高效和安全。大多数现有的MOT方法基于检测,即通过检测跟踪(TBD),并且仅使用单个深度传感器,如激光雷达来检测和跟踪目标。然而,长距离的非常稀疏的点云导致这些方法无法生成非常精确的检测结果,从而影响跟踪结果。因此,本文提出了一种基于传感器融合的3D MOT方法,利用激光雷达和摄像机的检测结果。
3D多目标跟踪新思路!基于多传感器融合的加权几何距离关联方法
|
机器学习/深度学习 传感器 算法
基于Matlab计算天线阵列方向图和绘制方向图
基于Matlab计算天线阵列方向图和绘制方向图
3. 模型的方向问题
3. 模型的方向问题
83 0
|
人工智能 开发者 Python
边缘分布 | 学习笔记
快速学习边缘分布
234 0
边缘分布 | 学习笔记