2019-11-18 16:46:03 donaldsy 阅读数 9

相关理论

几何矩

  • 几何矩 Mji=x,y(P(x,y)xjyi)M_{j i}=\sum_{x, y}\left(P(x, y) \cdot x^{j} \cdot y^{i}\right),其中(i+j)和等于几就叫做几阶距

  • 中心距muji=x,y(P(x,y)(xxˉ)j(yyˉ)i)m u_{j i}=\sum_{x, y}\left(P(x, y) \cdot(x-\bar{x})^{j} \cdot(y-\bar{y})^{i}\right),其中xˉ,yˉ\bar{x}, \bar{y}表示它的中心质点。

  • 中心归一化距nuji=mujim00(i+j)/2+1\mathrm{nu}_{j i}=\frac{\mathrm{mu}_{j i}}{\mathrm{m}_{00}^{(i+j) / 2+1}}

  • 矩的概念介绍

    • 图像中心Center(x0,y0)
      x0=m10m00y0=m01m00\mathrm{x}_{0}=\frac{m_{10}}{m_{00}} y_{0}=\frac{m_{01}}{m_{00}}
  • API介绍与使用-计算矩cv::moments

moments(
    InputArray  array,//输入数据
    bool   binaryImage=false // 是否为二值图像
)

contourArea(
    InputArray  contour,//输入轮廓数据
    bool   oriented// 默认false、返回绝对值
)

arcLength(
    InputArray  curve,//输入曲线数据
    bool   closed// 是否是封闭曲线
)

代码 & 效果展示

  • 演示代码 - 步骤
    • 提取图像边缘
    • 发现轮廓
    • 计算每个轮廓对象的矩
    • 计算每个对象的中心、弧长、面积

相关代码:

#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc/types_c.h>

using namespace std;
using namespace cv;

#ifndef P31
#define P31 31
#endif

#if P31 //图形矩形
Mat src, gray_src;
int threshold_value = 80;
int threshold_max = 255;
const char* output_win = "image moents demo";
RNG rng(12345);

void Demo_Moments(int, void*) {
    Mat canny_output;
    vector<vector<Point>> contours;
    vector<Vec4i> hierachy;

    Canny(gray_src, canny_output, threshold_value, threshold_value * 2, 3, false);
    findContours(canny_output, contours, hierachy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));

    vector<Moments> contours_moments(contours.size());
    vector<Point2f> ccs(contours.size());
    for (size_t i = 0; i < contours.size(); i++) {
        contours_moments[i] = moments(contours[i]);
        ccs[i] = Point(static_cast<float>(contours_moments[i].m10 / contours_moments[i].m00), static_cast<float>(contours_moments[i].m01 / contours_moments[i].m00));
    }

    Mat drawImg;// = Mat::zeros(src.size(), CV_8UC3);
    src.copyTo(drawImg);
    for (size_t i = 0; i < contours.size(); i++) {
        if (contours[i].size() < 100) {
            continue;
        }
        Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
        printf("center point x : %.2f y : %.2f\n", ccs[i].x, ccs[i].y);
        printf("contours %d area : %.2f   arc length : %.2f\n", i, contourArea(contours[i]), arcLength(contours[i], true));
        drawContours(drawImg, contours, i, color, 2, 8, hierachy, 0, Point(0, 0));
        circle(drawImg, ccs[i], 2, color,2, 8);
    }

    imshow(output_win, drawImg);
    return;
}
#endif

int main() {
    std::string path = "../circle.JPG";
    cv::Mat img = cv::imread(path, 5);

    string str_input = "input image";
    string str_output = "output image";

    if (img.empty()) {
        std::cout << "open file failed" << std::endl;
        return -1;
    }

    namedWindow(str_input, WINDOW_AUTOSIZE);
    namedWindow(str_output, WINDOW_AUTOSIZE);
    imshow(str_input, img);

#if P31
    src = img;
    cvtColor(src, gray_src, CV_BGR2GRAY);
    GaussianBlur(gray_src, gray_src, Size(3, 3), 0, 0);

    char input_win[] = "input image";
    namedWindow(input_win, WINDOW_AUTOSIZE);
    namedWindow(output_win, WINDOW_AUTOSIZE);
    imshow(input_win, src);

    createTrackbar("Threshold Value : ", output_win, &threshold_value, threshold_max, Demo_Moments);
    Demo_Moments(0, 0);
#endif

    cv::waitKey(0);
    cv::destroyAllWindows();
    return 0;
}

展示效果:
在这里插入图片描述

2017-07-14 16:43:38 u011600592 阅读数 1296

图像处理之计算二值连通区域的质心

一:几何距(Geometric Moments)知识与质心寻找原理

1. Image Moments是图像处理中非常有用的算法,可以用来计算区域图像

的质心,方向等几何特性,同时Mpq的高阶具有旋转不变性,可以用来

实现图像比较分类,正是因为Moments有这些特性,很多手绘油画效果

也会基于该算法来模拟实现。它的数学表达为:


它的低阶M00,M01, M10可以用来计算质心,中心化以后M11,M02,M20

可以用来计算区域的方向/角度

2. 什么是质心

就是通过该点,区域达到一种质量上的平衡状态,可能物理学上讲的比较多,简单点的

说就是规则几何物体的中心,不规则的可以通过挂绳子的方法来寻找。


二:算法流程

1.      输入图像转换为二值图像

2.      通过连通组件标记算法找到所有的连通区域,并分别标记

3.      对每个连通区域运用计算几何距算法得到质心

4.      用不同颜色绘制连通区域与质心,输出处理后图像

三:算法效果


左边为原图, 右边蓝色为连通组件标记算法处理以后结果,白色点为质心

四:关键代码解析

1.      计算几何距算法代码

doublem00 = moments(pixels, width, height, 0, 0);

doublexCr = moments(pixels, width, height, 1, 0) / m00;// row

doubleyCr = moments(pixels, width, height, 0, 1) / m00;// column

return new double[]{xCr, yCr};

2.      连通组件标记算法代码参见这里:

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

五:程序源代码

package com.gloomyfish.image.moments;

import java.awt.image.BufferedImage;

import com.gloomyfish.filter.study.AbstractBufferedImageOp;
import com.gloomyfish.rice.analysis.FastConnectedComponentLabelAlg;
// Geometric Moments Computing
// low-order moments - calculate the center point
// second-order moments - get angle size
// projection - 
public class GeometricMomentsFilter 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 center point of each region area(connected component)
        int[] input = new int[labels.length];
        GeometricMomentsAlg momentsAlg = new GeometricMomentsAlg();
        momentsAlg.setBACKGROUND(0);
        double[][] labelCenterPos = new double[max][2];
        for(int i=1; i<=max; i++)
        {
        	for(int p=0; p<input.length; p++)
        	{
        		if(labels[p] == i)
        		{
        			input[p] = labels[p];        			
        		}
        		else
        		{
        			input[p] = 0;
        		}
        	}
        	labelCenterPos[i-1] = momentsAlg.getGeometricCenterCoordinate(input, width, height);
        }
        
        // 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
        		}
        	}
        }
        
        // 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;
	}

}



2016-06-20 17:20:03 u010369450 阅读数 2153

本文为个人入门摘录总结,如有错误请包涵

后续还会加入相应图像代码,因为只是字面上理解,应该存在很多的偏差

比如说Hu矩的基于直角坐标系是指规格化吗?

不变矩(目前只大致学习了经典矩)相关Review如下图


不变矩

简述不变矩及无偏估计与有偏估计

矩描述子类似于力学的求质量,中心转动惯量等,具备不受平移旋转等影响的优点。

设A'=g(X1,X2,...,Xn)是未知参数A的一个点估计量,若A'满足
E(A')= A
则称A'为A的无偏估计量,否则为有偏估计量


矩的定义


p+q阶原点矩:

p+q阶中心矩:
在图像处理中因为图像是一个个像素组合而成,因此应该使用离散形式,在此不再赘述。

矩的规格化(归一化)即将中心矩用零阶中心矩来规格化:
归一化的原因:直接使用普通矩或者中心矩进行特征表示,不能使特征同时具有平移,旋转以及比例不变性,如果利用归一化中心矩,则特征不仅具备平移不变性,而且还具备比例不变性

矩特征表征了图像区域的几何特征又称为几何矩,因为具备旋转,平移以及尺度等特征的不变特征,因此称为不变特征
称为不变矩。
几何不变矩可以用来作为重要的特征来表示物体,进行相关分类,在人形识别常用的不变矩主要有Hu矩Zernike矩

Hu矩

Hu于1961年首先提出了基于直角坐标系的规则矩的概念(来自文章Pattern Recognition by Moment Invariants),之后运用规则矩的非线性组合得到了一套具备尺度不变性,平移不变性以及旋转不变性的矩不变量(来自文章Visual Pattern Recognition by Moment Invariant)。(本段还将增补)
Hu矩的定义,基本性质具备平移,旋转缩放不变性的7个不变矩表达式
7个表达式太长不再赘述,这里附上原文链接:
http://read.pudn.com/downloads155/ebook/687948/Pattern%20Recognition%20by%20Moment%20Invariant.pdf
提取Hu矩方案为
1,输入预处理后的图像。2,计算零阶以及一阶矩。3,计算三阶以下中心矩
4,归一化中心矩。 5,计算7个Hu不变矩



Zernike矩

Zernike矩为基于Zernike多项式的正交化函数,所利用的正交多项式集(完备性是指在数学及其相关领域中,当一个对象具有完备性,即它不需要添加任何其他元素,这个对象也可称为完备的或完全的。  正交的完备性在线性空间中就是指构成这个空间的基是相互正交的,即这个空间中所有的向量都可以由这组基线性表出,而且这些基又相互正交.)Zernike矩源自于Teague提出的正交矩思想,相较于Hu矩,其具备良好的旋转不变性,作为正交矩能够构造任意的高阶矩,运算为积分运算,因此对噪声不敏感。

当计算一幅图像的Zernike矩时,以该图像的形心(也称为原点)把像素坐标映射到单位圆内

Zernike矩是图像函数f(x,y)在正交多项式上的投影,其中正交多项式在单位圆内正交

Zernike矩提取方案为:

1,输入预处理后的图像。2,找出目标最小外接矩形。3,计算各阶矩
4,归一化Zernike矩。 

Zernike矩与Hu矩及其应用

1)优点:

不变矩不受旋转以及大小的影响,可以将其应用于识别二维或者三维物体。

2)缺点:

①不变矩对噪声很敏感,因此有其他作者提出相关不变矩对上述进行改进。

②矩计算时间比较长。

③矩是一种整体性质,如果物体的一部分被其他物体遮挡,则无法计算不变矩。比如说角点是一种描述局部的性质

④Hu提出的不变矩只能对区域进行检测,不能用于边界的检测;对于区域的检测,总体上来说,极半径不变矩与Hu矩的效果相当;但是Hu矩收到图形对称性的影响,而极半径不变矩不受到图形对称性的影响,所以对于对称图形来说,极半径不变矩的效果要优于Hu不变矩

3)应用:

Hu和Zernike矩都具备平移旋转以及缩放的不变性,但是各有特点。Hu的目标信息不是很全面,含有较多的冗余信息;Zernike矩是正交矩,能够构造出任意的高阶矩,包含信息全面,对噪声不敏感。可采用不变矩应用于人形识别算法。


Harris角点检测

Harris角点检测由Chris Harris和Mike Stephens于1988年在A COMBINED CORNER AND EDGE DETECTOR一文中提出

角点检测基础

图像变化类型:

有几何变换和灰度变换。

几何变换又可以分为旋转,仿射(非各项同性的缩放)以及相似(各项同性的缩放)

特征点提取的作用:

是许多计算机视觉算法的基础——使用特征点来代表图像的内容
运动目标跟踪
物体识别
图像配准
全景图像拼接
三维重建

角点的定义以及发展:

角点:

最直观的印象就是在水平、竖直两个方向上变化均较大的点,即Ix、Iy都较大
边缘:仅在水平、或者仅在竖直方向有较大的变化量,即Ix和Iy只有其一较大
平坦地区:在水平、竖直方向的变化量均较小,即Ix、Iy都较小

好的角点算法定义:

检测出图像中“真实的”角点
准确的定位性能
很高的重复检测率(稳定性好)
具有对噪声的鲁棒性
具有较高的计算效率


角点算法的发展:典型的角点检测算法有Harris算法以及CSS算法


其中Harris算法由Chris Harris和Mike Stephens于1988年在A COMBINED CORNER AND EDGE DETECTOR一文中提出

Harris角点算法思想以及实现

Harris角点算法思想:

由局部小窗口观察图像特征,角点定义:窗口向任意方向的移动都导致图像灰度的明显变化

Harris角点性质:

更多角点评价:Evaluation of Interest Point Detectors(IJCV 2000)

具备旋转不变性(椭圆转过一定角度,但是其形状保持不变,即特征值保持不变,角点响应函数R对于图像的旋转具备不变性)

对于图像灰度的仿射变化具备部分的不变性(只使用了图像导数,对于灰度平移变化不变,对于图像灰度的尺度变化

对于尺度变换不具备不变性

Harris角点的实现:定义了灰度变化函数(窗函数*灰度平移前后变化差的平方)以及角点响应函数R

灰度平移前后变化差可以进行泰勒展开,取二阶导及以后项为极小项,相减后即可以得到一个窗口响应函数,根据窗口响应函数分布根据窗口响应函数可以定义角点响应函数R=det M - k(trace M)²【这块的推导应该进行相关研究。 对角点响应函数的理解?

算法:首先对角点响应函数R进行阈值处理(R>threshold)然后提取R的局部极大值




2010-07-23 15:06:00 deco1515 阅读数 8416

          平稳时间序列是ARMA模型的建模前提,对时间序列进行平稳性的判断是预测的首要步骤。一般而言,所谓的平稳时间序列是指宽平稳过程,即是一阶距与时间无关,二阶距只与时间间隔有关。有几种判断方法:1)数据图直接检验法。画出X(t)的图像,当x(t)围绕某一水平线上下波动而无明显上升、下降或周期趋势时,则认为x(t)是平稳的。(简单直接,我喜欢!)

2)自相关、偏相关函数检验法。一个零均值平稳序列的自相关函数和偏自相关函数要么是截尾的,要么是拖尾的。因此,如果一个序列零均值化以后的自相关函数或偏自相关函数既不截尾,又不拖尾则可以断定该序列时非平稳的。(方法有点晕,还需要再查查资料??)

3)特征根检验法。先拟合序列的适应模型,然后求由适应模型的参数组成的特征方程的特征根,若所有的特征根都满足平稳性条件,abs(namta)<1则可认为该序列时平稳的,否则该序列是非平稳的。其中namta为特征根。

4)Rk检验。根据Green函数Gj与自协方差函数Rk之间的关系,当{xt}是平稳时间序列时,Gj的极限趋于0,表示稳定系统的单位脉冲响应最终将衰减至0。(见杨叔子p181)。


          事实上,除了平稳性检验外,还有正态性检验,零均值性检验。正态性检验往往可以省略,零均值性可以根据工程实际来判断。


           数据预处理一般包括了剔除野点,平稳化,零均值化。剔除野点只需要根据性x(t)的图形,去除一些太离谱的点即可。平稳化的实质是将数据的趋势性和周期性去掉。(应该牢牢把握这一点!!)


          一般常用的平稳化方法是差分。对有线性趋势的时序进行一次差分,如果序列有二次趋势,则一般两次差分可变换为平稳序列。我也尝试过先对数据进行一次或二次曲线拟合,再用原始数据减去拟合的数据得到平稳序列,但效果不好(???头疼)


           零均值化即是求出时序均值,然后用数据去减一减。

2011-09-23 10:11:07 zhubenfulovepoem 阅读数 3519

Question:以下两幅图像,判断出哪个有孔,并计算出图中勺子的最窄处的宽度?

代码下载:http://www.pudn.com/downloads386/sourcecode/graph/texture_mapping/detail1655727.html


我用vc++编写的识别框架如下:

1.运行界面打开图像:

2.点击区域分割与提取:


3.进行多次中值滤波,然后进行一次一阶微分运算,运算结果放大两倍,然后去25二值化得到边界图:


然后计算最后操那个图的像素总值,2.bmp显示结果为接近6000;求得最短就离为31个像素点,利用length=nmin/28.346这个即可求出距离。


关键代码:

/*----Threshold----二值化处理------------------------

image_in 输入图像数据指针

image_out 输出图像数据指针

xsize   图像宽度

ysize   图像高度

thresh  阈值(0-255)

mode    处理方法(1,2)

--------------------------------------------------*/

 

void Threshold(BYTE *image_in,BYTE*image_out,int xsize,int ysize,int thresh,int mode)

       {

              inti,j;

              for(j=0;j<ysize;j++)

              {

                     for(i=0;i<xsize;i++)

                     {

                            switch(mode)

                            {

                            case2:

                                   if(*(image_in+i+j*xsize)<=thresh)

                                          *(image_out+i+j*xsize)=HIGH;

                                   else

                                          *(image_out+i+j*xsize)=LOW;

                                   break;

                            default:

                                   if(*(image_in+i+j*xsize)>=thresh)

                                          *(image_out+i+j*xsize)=HIGH;

                                   else

                                          *(image_out+i+j*xsize)=LOW;

                                   break;

                            }

                     }    

              }

       }

//中值子函数

int median_value(BYTE c[9])

{

       inti,j,buf;

       for(j=0;j<8;j++){

              for(i=0;i<8;i++){

                     if(c[i+1]<c[i]){

                            buf=c[i+1];

                            c[i+1]=c[i];

                            c[i]=buf;

                     }

              }

       }

       returnc[4];

}

//中值滤波

void Median(BYTE *image_in, BYTE*image_out, int xsize, int ysize)

{

       inti,j;

       unsignedchar c[9];

       for(i=1;i<ysize-1;i++){

              for(j=1;j<xsize-1;j++){

              c[0]=*(image_in+(i-1)*xsize+j-1);

              c[1]=*(image_in+(i-1)*xsize+j);

              c[2]=*(image_in+(i-1)*xsize+j+1);

              c[3]=*(image_in+i*xsize+j-1);

              c[4]=*(image_in+i*xsize+j);

              c[5]=*(image_in+i*xsize+j+1);

              c[6]=*(image_in+(i+1)*xsize+j-1);

              c[7]=*(image_in+(i+1)*xsize+j);

              c[8]=*(image_in+(i+1)*xsize+j+1);

              *(image_out+i*xsize+j)=median_value(c);

              }

       }

}

 

/*--------------------------提取轮廓-----------------------------*

 

//1阶微分边沿检出(梯度算子)

amp    //输出像素值倍数

roberts算子:g(x,y)=abs(f(x,y)-f(x+1,y+1))+abs(f(x,y+1)-f(x+1,y))

Roberts边缘检测算子是一种利用局部差分算子寻找边缘的算子,Robert算子图像处理后结果边缘不是很平滑。

经分析,由于Robert算子通常会在图像边缘附近的区域内 产生较宽的响应,

故采用上述算子检测的边缘图像常需做细化处理,边缘定位的精度不是很高。

 

卷积运算:可看作是加权求和的过程,使用到的图像区域中的每个像素

分别于卷积核(权矩阵)的每个元素对应相乘,所有乘积之和作为区域中心像素的新值。

 

连续空间的卷积定义是f(x)与g(x)的卷积是 f(t-x)g(x) 在t从负无穷到正无穷的积分值.t-x要在f(x)定义域内

所以看上去很大的积分实际上还是在一定范围的

把积分符号换成求和就是离散空间的卷积定义了.那么在图像中卷积卷积地是什么意思呢,

就是图像就是图像f(x),模板是g(x),然后将模版g(x)在模版中移动,每到一个位置,

就把f(x)与g(x)的定义域相交的元素进行乘积并且求和,得出新的图像一点,就是被卷积后的图像.

------------------------------------------------------------------*/

void Differential(BYTE *image_in, BYTE*image_out, int xsize, int ysize, float amp)

{

       staticint cx[9]={0,0,0,0,1,0,0,0,-1};  //算子X(roberts)

       staticint cy[9]={0,0,0,0,0,1,0,-1,0};  //算子y(roberts)

       intd[9];

       inti,j,dat;

       floatxx,yy,zz;

 

       for(j=1;j<ysize-1;j++)

       {

              for(i=1;i<xsize;i++)

              {

                     d[0]=*(image_in+(j-1)*xsize+i-1);

                     d[1]=*(image_in+(j-1)*xsize+i);

                     d[2]=*(image_in+(j-1)*xsize+i+1);

                     d[3]=*(image_in+j*xsize+i-1);

                     d[4]=*(image_in+j*xsize+i);

                     d[5]=*(image_in+j*xsize+i+1);

                     d[6]=*(image_in+(j+1)*xsize+i-1);

                     d[7]=*(image_in+(j+1)*xsize+i);

                     d[8]=*(image_in+(j+1)*xsize+i+1);//在图像上取出3*3的像素值

 

                     xx=(float)(cx[0]*d[0]+cx[1]*d[1]+cx[2]*d[2]+cx[3]*d[3]+cx[4]*d[4]+

                            cx[5]*d[5]+cx[6]*d[6]+cx[7]*d[7]+cx[8]*d[8]);

                     yy=(float)(cy[0]*d[0]+cy[1]*d[1]+cy[2]*d[2]+cy[3]*d[3]+cy[4]*d[4]+

                            cy[5]*d[5]+cy[6]*d[6]+cy[7]*d[7]+cy[8]*d[8]);

                    

                     zz=(float)(amp*sqrt(xx*xx+yy*yy));

                     dat=(int)zz;

 

                     if(dat>255)dat=255;

                     *(image_out+j*xsize+i)=dat;

              }

       }

 

}

//膨胀

void Dilation(BYTE *image_in, BYTE*image_out, int xsize, int ysize)

{

       inti,j;

       for(j=1;j<ysize-1;j++){

              for(i=1;i<xsize-1;i++){

                     *(image_out+j*xsize+i)=*(image_in+j*xsize+i);

                     if(*(image_in+(j-1)*xsize+i-1)==HIGH)

                     *(image_out+j*xsize+i)=HIGH;

                     if(*(image_in+(j-1)*xsize+i)==HIGH)

                     *(image_out+j*xsize+i)=HIGH;

                     if(*(image_in+(j-1)*xsize+i+1)==HIGH)

                     *(image_out+j*xsize+i+1)=HIGH;

                     if(*(image_in+j*xsize+i-1)==HIGH)

                     *(image_out+j*xsize+i)=HIGH;

                     if(*(image_in+j*xsize+i+1)==HIGH)

                     *(image_out+j*xsize+i)=HIGH;

                     if(*(image_in+j*xsize+i)==HIGH)

                     *(image_out+j*xsize+i)=HIGH;

                     if(*(image_in+(j+1)*xsize+i-1)==HIGH)

                     *(image_out+j*xsize+i)=HIGH;

                     if(*(image_in+(j+1)*xsize+i+1)==HIGH)

                     *(image_out+j*xsize+i)=HIGH;

                     if(*(image_in+(j+1)*xsize+i)==HIGH)

                     *(image_out+j*xsize+i)=HIGH;

              }

       }

 

}

//腐蚀

void Erodible(BYTE *image_in, BYTE*image_out, int xsize, int ysize)

{

       inti,j;

       for(j=1;j<ysize-1;j++){

              for(i=1;i<xsize-1;i++){

                     *(image_out+j*xsize+i)=*(image_in+j*xsize+i);

                     if(*(image_in+(j-1)*xsize+i-1)==LOW)

                     *(image_out+j*xsize+i)=LOW;

                     if(*(image_in+(j-1)*xsize+i)==LOW)

                     *(image_out+j*xsize+i)=LOW;

                     if(*(image_in+(j-1)*xsize+i+1)==LOW)

                     *(image_out+j*xsize+i+1)=LOW;

                     if(*(image_in+j*xsize+i-1)==LOW)

                     *(image_out+j*xsize+i)=LOW;

                     if(*(image_in+j*xsize+i+1)==LOW)

                     *(image_out+j*xsize+i)=LOW;

                     if(*(image_in+j*xsize+i)==LOW)

                     *(image_out+j*xsize+i)=LOW;

                     if(*(image_in+(j+1)*xsize+i-1)==LOW)

                     *(image_out+j*xsize+i)=LOW;

                     if(*(image_in+(j+1)*xsize+i+1)==LOW)

                     *(image_out+j*xsize+i)=LOW;

                     if(*(image_in+(j+1)*xsize+i)==LOW)

                     *(image_out+j*xsize+i)=LOW;

              }

       }

}

/********************************************************************/

//求像素总和

int i,j;

       for(j=1;j<m_nysize-1;j++){

              for(i=1;i<m_nxsize-1;i++){

                     *(m_pImage_out+j*m_nxsize+i)=*(m_pImage_in+j*m_nxsize+i);

                     if(*(m_pImage_in+j*m_nxsize+i-1)==HIGH)

                            m_nSum++;

              }

       }

 

       SetDlgItemInt(IDC_SUM,m_nSum,TRUE);

 

/**********************************************************************/

求最短距离

int i,j;

       intxx,yy;

       intjj=0;

       intii=0;

       intsumiy[429]={0};

       intsumjy[429]={0};

       intsum[429]={1};

       intiy[116]={0};

       intjy[116]={0};

       intnmin=100;//最短距离初值

 

       for(j=1;j<m_nysize-1;j++)

       {

              for(i=1;i<m_nxsize-1;i++)//求出某一行在横坐标方向上的左起像素岂起始点

              {

                     //*(m_pImage_out+j*m_nxsize+i)=*(m_pImage_in+j*m_nxsize+i);

                     if(*(m_pImage_in+j*m_nxsize+i-1)==HIGH)

                            xx=1;

                     if(xx==1)

                     {

                            iy[jj]=i;

                            jj++;

                     }

              }

              sumiy[j]=iy[1];

 

      

              for(i=m_nxsize-1;i>1;i--)//求出某一行在横坐标方向上的右起像素岂起始点

              {

                     if(*(m_pImage_in+j*m_nxsize+i-1)==HIGH)

                            yy=1;

                     if(ii==1)

                     {

                            jy[ii]=i;

                            ii++;

                     }

              }

              sumjy[j]=jy[1];

 

              sum[j]=abs(sumjy[j]-sumiy[j]);//求出某一行在横坐标方向上的像素区间

       }

 

 

       for(j=1;j<427;j++)

       {

        //求出所有行中在在横坐标方向像素区间最小的距离

              if((sum[j]>30) && (sum[j]<100))//排除错误成分

                     {

                            if( sum[j]<nmin )

                            {

                                   nmin=sum[j];

 

                            }

                     }

       }

       SetDlgItemInt(IDC_MIN,nmin,TRUE);


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