2016-02-26 21:05:45 u013369277 阅读数 2673
  • MATLAB基础知识大串讲

    Matlab基础知识大串讲,具体内容包括matlab下载安装、数据类型、矩阵操作、运算符、字符串处理、数组运算、M文件、变量、控制流、脚本与函数、图形绘制、二维图形绘制、三维图形绘制、四维图形绘制。

    32940 人正在学习 去看看 魏伟

调用的框架:http://blog.chinaunix.net/uid-20622737-id-3173056.html
实验内容:
对于下面这幅图像,编程实现染色体计数,并附简要处理流程说明。
这里写图片描述
处理步骤:
1. 读取图像,转换为灰度图像

  1. 平滑滤波去噪

  2. 图像二值化

  3. 对图像进行膨胀

  4. 再次膨胀(视情况而定)

  5. 腐蚀(视情况而定)

  6. 反转

  7. 统计连通区域个数并输出

  8. 保存图像。

void main()
{
    Bitmap *bmp = (Bitmap *)malloc(sizeof(Bitmap));// build an empty bmp to put the img.空变量呈放图片
    Bitmap *dstBmp = (Bitmap *)malloc(sizeof(Bitmap));
    Bitmap *graybmp = (Bitmap *)malloc(sizeof(Bitmap));
    Bitmap *smoothbmp = (Bitmap *)malloc(sizeof(Bitmap));
    Bitmap *binbmp = (Bitmap *)malloc(sizeof(Bitmap));
    Bitmap *temp = (Bitmap *)malloc(sizeof(Bitmap));
    int ret;
    char *path ="C:\\Users\\Ali\\Desktop\\1.bmp";
    ret = ReadBitmap(path, bmp);//读取图片
    char *savePath ="C:\\Users\\Ali\\Desktop\\zuizhong.bmp";
    RGB2Gray(bmp,graybmp);//转换成灰度图
    smooth(graybmp,smoothbmp);
    Gray2BW(smoothbmp,binbmp,155);//二值化
    pengzhang(binbmp, dstBmp);  
    pengzhang(dstBmp, temp);
    fushi(temp,dstBmp);
    qufan(dstBmp,temp);
    /*BYTE *bitmap = temp->imageData;
    int width = temp->width;
    int height = temp->height;
    int *labelmap;
    ConnectedComponentLabeling(bitmap, width, height,labelmap); 有待调整 此处是调用本博客的另一篇文章
    二值图像统计连通区域*/
    SaveBitmap(savePath,temp);//保存图片    
}

bmp.h

#ifndef BMP_H_INCLUDED
#define BMP_H_INCLUDED

#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>

/**
 * 位图文件结构及基本函数定义  打开和保存bmp文件
 */
typedef unsigned short WORD;
typedef unsigned long DWORD;
typedef long LONG;
typedef unsigned char BYTE;

/* 位图文件头结构 14字节 */
typedef struct tagBITMAPFILEHEADER {
    WORD bfType;
    DWORD bfSize;
    WORD bfReserved1;
    WORD bfReserved2;
    DWORD bfOffBits;
} BITMAPFILEHEADER;

/* 位图信息头结构 40字节 */
typedef struct tagBITMAPINFOHEADER {
    DWORD biSize; // 结构长度 40B
    LONG biWidth;
    LONG biHeight;
    WORD biPlanes; // 1
    WORD biBitCount; // 表示颜色要用到的位数
    DWORD biCompression; // 压缩格式
    DWORD biSizeImage; // 位图占用字节数=biWidth'(4的整倍数)*biHeight
    LONG biXPelsPerMeter; // 水平分辨率
    LONG biYPelsPerMeter; // 垂直分辨率
    DWORD biClrUsed; // 本图像用到的颜色数
    DWORD biClrImportant; // 本图像的重要颜色数
} BITMAPINFOHEADER;

/* 调色板 4字节 */
typedef struct tagRGBQUAD {
    BYTE rgbBlue;
    BYTE rgbGreen;
    BYTE rgbRed;
    BYTE rgbReserved;
} RGBQUAD;

/* 定义图像信息 */
typedef struct tagBITMAPINFO {
    BITMAPINFOHEADER bmiHeader;
    RGBQUAD bmiColors[1];
} BITMAPINFO;

/* 定义位图图像 */
typedef struct _Bitmap
{
    BITMAPFILEHEADER bmfh;
    BITMAPINFOHEADER bmih;
    int width;
    int height;
    int bitCount;    // 8 或者24
    int imageSize;    // 图像数据大小(imageSize=height*widthStep)字节
    BYTE* imageData;//排列的图像数据
    int widthStep;    //排列的图像行大小
}Bitmap;

/**
 * 位图创建函数  创建一个Bitmap结构,并为图像数据分配空间
 *
 * 使用方法:
 *     Bitmap *bmp=(Bitmap*)malloc(sizeof(Bitmap));
 *     ret=CreateBitmap(bmp,50,50,3);
 */
int CreateBitmap(Bitmap* bmp, int width, int height, int bitCount)
{
    bmp->width=width;
    bmp->height=height;
    bmp->bmih.biWidth=width;
    bmp->bmih.biHeight=height;

    bmp->widthStep=(int)((width*bitCount+31)/32)*4;        //计算排列的宽度
    bmp->imageSize=bmp->height*bmp->widthStep*sizeof(BYTE);//计算排列的图像大小

    if(bitCount==8)
    {
        bmp->bitCount=8;
        bmp->bmfh.bfType=0x4d42;    //注意是4d42 这个地方折磨我一下午啊
        bmp->bmfh.bfReserved1=0;
        bmp->bmfh.bfReserved2=0;
        bmp->bmih.biBitCount=8;
        bmp->bmih.biSize=40;
        bmp->bmih.biPlanes=1;
        bmp->bmfh.bfSize=54+256*4+height*bmp->widthStep;
        bmp->bmfh.bfOffBits=1078;
        bmp->bmih.biBitCount=8;
        bmp->bmih.biCompression=0;
        bmp->bmih.biSizeImage=bmp->imageSize;
        bmp->bmih.biClrUsed=0;
        bmp->bmih.biClrImportant=0;
        bmp->bmih.biXPelsPerMeter=0;
        bmp->bmih.biYPelsPerMeter=0;
    }
    else if (bitCount==24)
    {
        bmp->bitCount=24;
        bmp->bmfh.bfType=0x4d42;
        bmp->bmih.biBitCount=24;
        bmp->bmfh.bfReserved1=0;
        bmp->bmfh.bfReserved2=0;
        bmp->bmih.biSize=40;
        bmp->bmih.biPlanes=1;
        bmp->bmfh.bfSize=54+height*bmp->widthStep;
        bmp->bmfh.bfOffBits=54;
        bmp->bmih.biBitCount=24;
        bmp->bmih.biSizeImage=bmp->imageSize;
        bmp->bmih.biClrUsed=0;
        bmp->bmih.biCompression=0;
        bmp->bmih.biClrImportant=0;
        bmp->bmih.biXPelsPerMeter=0;
        bmp->bmih.biYPelsPerMeter=0;
    }
    else
    {
        printf("Error(CreateBitmap): only supported 8 or 24 bits bitmap.\n");
        return -1;
    }

    bmp->imageData=(BYTE*)malloc(bmp->imageSize);        //分配数据空间
    if(!(bmp->imageData))
    {
        printf("Error(CreateBitmap): can not allocate bitmap memory.\n");
        return -1;
    }
    return 0;
}

/**
 * 位图指针释放函数  释放位图数据空间
 *
 * 使用方法:
 *     ReleaseBitmap(bmp);
 */
void ReleaseBitmap(Bitmap* bmp)
{
    free(bmp->imageData);
    bmp->imageData=NULL;
    free(bmp);
    bmp=NULL;
}

/**
 * 路径检查函数:是否为BMP文件,是否可读
 * 正确返回0,错误返回-1
 *
 * 使用方法
 *         ret=CheckPath(path);
 */
int CheckPath(char *path)
{
    FILE *fd;
    int len = strlen(path) / sizeof(char);
    char ext[3];
    //check whether the path include the characters "bmp" at end
    strncpy(ext, &path[len - 3], 3);
    if (!(ext[0] == 'b' && ext[1] == 'm' && ext[2] == 'p')) {
        printf("Error(CheckPath): the extension of the file is not bmp.\n");
        return -1;
    }

    //check whether the file can be read or not
    fd = fopen(path, "r");
    if (!fd)
    {
        printf("Error(CheckPath): can not open the file.\n");
        return -1;
    }
    fclose(fd);

    return 0;
}

/**
 * 从文件中读取位图de函数
 * 正确返回0,错误返回-1
 *
 * 使用方法:
 *     bmp=(Bitmap*)malloc(sizeof(Bitmap));
 *     ret=ReadBitmap(path, bmp);
 */
int ReadBitmap(char* path, Bitmap* bmp)
{
    int ret;
    FILE *fd;

    //检查路径是否可读
    ret=CheckPath(path);
    if(ret==-1)
    {
        printf("Error(ReadBitmap): the path of the image is invalid.\n");
        return -1;
    }

    //打开文件
    fd=fopen(path,"rb");
    if(fd==0)
    {
        printf("Error(ReadBitmap): can not open the image.\n");
        return -1;
    }

    //读取文件信息头     14字节
    fread(&(bmp->bmfh.bfType),sizeof(WORD),1,fd);
    fread(&(bmp->bmfh.bfSize),sizeof(DWORD),1,fd);
    fread(&(bmp->bmfh.bfReserved1),sizeof(WORD),1,fd);
    fread(&(bmp->bmfh.bfReserved2),sizeof(WORD),1,fd);
    fread(&(bmp->bmfh.bfOffBits),sizeof(DWORD),1,fd);

    //读取位图信息头    40字节
    fread(&(bmp->bmih.biSize),sizeof(DWORD),1,fd);
    fread(&(bmp->bmih.biWidth),sizeof(DWORD),1,fd);
    fread(&(bmp->bmih.biHeight),sizeof(DWORD),1,fd);
    fread(&(bmp->bmih.biPlanes),sizeof(WORD),1,fd);
    fread(&(bmp->bmih.biBitCount),sizeof(WORD),1,fd);
    fread(&(bmp->bmih.biCompression),sizeof(DWORD),1,fd);
    fread(&(bmp->bmih.biSizeImage),sizeof(DWORD),1,fd);
    fread(&(bmp->bmih.biXPelsPerMeter),sizeof(DWORD),1,fd);
    fread(&(bmp->bmih.biYPelsPerMeter),sizeof(DWORD),1,fd);
    fread(&(bmp->bmih.biClrUsed),sizeof(DWORD),1,fd);
    fread(&(bmp->bmih.biClrImportant),sizeof(DWORD),1,fd);

    //创建位图结构
    ret=CreateBitmap(bmp, bmp->bmih.biWidth, bmp->bmih.biHeight, bmp->bmih.biBitCount);
    if(ret==-1)
    {
        printf("Error(CreateBitmap): can not CreateBitmap.\n");
        return -1;
    }

    //读取图像数据
    //由于4字节对齐格式
    fseek(fd,bmp->bmfh.bfOffBits,SEEK_SET);    //定位到图像数据区
    ret=fread(bmp->imageData,bmp->imageSize,1,fd);
    if(ret==0)
    {
        if(feof(fd))    //if the file pointer point to the end of the file
        {
        }
        if(ferror(fd))  //if error happened while read the pixel data
        {
            printf("Error(ReadBitmap): can not read the pixel data.\n");
            fclose(fd);
            return -1;
        }
    }

    //关闭文件
    fclose(fd);
    return 0;
}

/**
 * 保存位图到文件中去
 * 正确返回0,错误返回-1
 *
 * 使用方法:
 *     bmp=(Bitmap*)malloc(sizeof(Bitmap));
 *     ret=SaveBitmap(path, bmp);
 */
int SaveBitmap(char* path, Bitmap* bmp)
{
    int ret;
    FILE *fd;

    //检查路径是否正确
    int len = strlen(path) / sizeof(char);
    char ext[3];
    //check whether the path include the characters "bmp" at end
    strncpy(ext, &path[len - 3], 3);
    if (!(ext[0] == 'b' && ext[1] == 'm' && ext[2] == 'p'))
    {
        printf("Error(SaveBitmap): the extension of the file is not bmp.\n");
        return -1;
    }

    //打开文件
    fd=fopen(path,"wb");
    if(fd==0)
    {
        printf("Error(SaveBitmap): can not open the image.\n");
        return -1;
    }

    //保存文件信息头     14字节
    fwrite(&(bmp->bmfh.bfType),sizeof(WORD),1,fd);
    fwrite(&(bmp->bmfh.bfSize),sizeof(DWORD),1,fd);
    fwrite(&(bmp->bmfh.bfReserved1),sizeof(WORD),1,fd);
    fwrite(&(bmp->bmfh.bfReserved2),sizeof(WORD),1,fd);
    fwrite(&(bmp->bmfh.bfOffBits),sizeof(DWORD),1,fd);

    //保存位图信息头    40字节
    fwrite(&(bmp->bmih.biSize),sizeof(DWORD),1,fd);
    fwrite(&(bmp->bmih.biWidth),sizeof(DWORD),1,fd);
    fwrite(&(bmp->bmih.biHeight),sizeof(DWORD),1,fd);
    fwrite(&(bmp->bmih.biPlanes),sizeof(WORD),1,fd);
    fwrite(&(bmp->bmih.biBitCount),sizeof(WORD),1,fd);
    fwrite(&(bmp->bmih.biCompression),sizeof(DWORD),1,fd);
    fwrite(&(bmp->bmih.biSizeImage),sizeof(DWORD),1,fd);
    fwrite(&(bmp->bmih.biXPelsPerMeter),sizeof(DWORD),1,fd);
    fwrite(&(bmp->bmih.biYPelsPerMeter),sizeof(DWORD),1,fd);
    fwrite(&(bmp->bmih.biClrUsed),sizeof(DWORD),1,fd);
    fwrite(&(bmp->bmih.biClrImportant),sizeof(DWORD),1,fd);

    //如果为8位,则 保存调色板
    RGBQUAD pal[256];
    int i;
    if(bmp->bitCount==8)
    {
        for(i=0;i<256;i++)
        {
            pal[i].rgbBlue=i;
            pal[i].rgbGreen=i;
            pal[i].rgbRed=i;
            pal[i].rgbReserved=0;
        }
        if(fwrite(pal,sizeof(RGBQUAD)*256,1,fd)!=1)
        {
            printf("Error(SaveBitmap): can not write Color Palette.\n");
            return -1;
        }
    }


    //保存图像数据
    ret=fwrite(bmp->imageData,bmp->imageSize,1,fd);
    if(ret!=1)
    {
        printf("Error(SaveBitmap): can not save the pixel data.\n");
        return -1;
    }

    //关闭文件
    fclose(fd);

    return 0;
}

#endif // BMP_H_INCLUDED

basicprocess.h

#ifndef BASICPROCESS_H_
#define BASICPROCESS_H_
#include <string.h>
#include <stdlib.h>
#include <malloc.h>
#include "bmp.h"
#include <math.h>
/**
 * <font color="#3f7f5f">位图图像基本处理函数  图像格式转换</font>
 */
int RGB2Gray(Bitmap* src, Bitmap* dst)
{
    int ret;
    int n=0,i,j;
    BYTE r,g,b,gray;

    //检查图像格式是否合法
    if(src->bitCount!=24)
    {
        printf("Error(RGB2Gray): the source image must be in RGB format.\n");
        return -1;
    }

    //为dst图像分配数据空间
    ret=CreateBitmap(dst,src->width,src->height,8);
    if(ret==-1)
    {
        printf("Error(RGB2Gray): can't create target image.\n");
        return -1;
    }

    //计算灰度数据
    for(i=0;i<src->height;i++)
    {
        n=0;
        for(j=0;j<src->width*3;j++,n++)
        {
            b=*(src->imageData+src->widthStep*(src->height-1-i)+j);
            j++;
            g=*(src->imageData+src->widthStep*(src->height-1-i)+j);
            j++;
            r=*(src->imageData+src->widthStep*(src->height-1-i)+j);
            gray=(r*19595 + g*38469 + b*7472) >> 16;
            *(dst->imageData+dst->widthStep*(dst->height-1-i)+n)=gray;
        }
    }

    return 0;
}

/**
 * Gray2RGB
 *
 * 使用方法:
 *        bmp=(Bitmap*)malloc(sizeof(Bitmap));
 *        ret=ReadBitmap(path, bmp);
 *        dstbmp=(Bitmap*)malloc(sizeof(Bitmap));
 *        ret=Gray2RGB(bmp,dstbmp);
 */
int Gray2RGB(Bitmap* src, Bitmap* dst)
{
    int ret;
    int n=0,i,j;
    BYTE r;

    //检查图像格式是否合法
    if(src->bitCount!=8)
    {
        printf("Error(Gray2RGB): the source image must be in gray scale.\n");
        return -1;
    }

    //为dst图像分配数据空间
    ret=CreateBitmap(dst,src->width,src->height,24);
    if(ret==-1)
    {
        printf("Error(Gray2RGB): can't create target image.\n");
        return -1;
    }

    //计算灰度数据
    for(i=0;i<src->height;i++)
    {
        n=0;
        for(j=0;j<src->width;j++,n++)
        {
            r=*(src->imageData+src->widthStep*(src->height-1-i)+j);
            *(dst->imageData+dst->widthStep*(dst->height-1-i)+n)=r;
            n++;
            *(dst->imageData+dst->widthStep*(dst->height-1-i)+n)=r;
            n++;
            *(dst->imageData+dst->widthStep*(dst->height-1-i)+n)=r;
        }
    }

    return 0;
}

/**
 * Gray2BW 图像二值化
 *
 * 使用方法:
 *        bmp=(Bitmap*)malloc(sizeof(Bitmap));
 *        ret=ReadBitmap(path, bmp);
 *        dstbmp=(Bitmap*)malloc(sizeof(Bitmap));
 *        ret=Gray2BW(bmp,dstbmp);
 */
int Gray2BW(Bitmap* src, Bitmap* dst, int threshold)
{
    int ret;
    int n=0,i,j;
    BYTE r;

    //检查图像格式是否合法
    if(src->bitCount!=8)
    {
        printf("Error(Gray2BW): the source image must be in gray scale.\n");
        return -1;
    }

    //为dst图像分配数据空间
    ret=CreateBitmap(dst,src->width,src->height,8);
    if(ret==-1)
    {
        printf("Error(Gray2BW): can't create target image.\n");
        return -1;
    }

    //计算灰度数据
    for(i=0;i<src->height;i++)
    {
        for(j=0;j<src->width;j++,n++)
        {
            r=*(src->imageData+src->widthStep*(src->height-1-i)+j);
            if(r>=threshold)
            {
                n=255;
            }
            else
            {
                n=0;
            }
            *(dst->imageData+dst->widthStep*(dst->height-1-i)+j)=n;
        }
    }

    return 0;
}

/**
 *  rgb2hsv
 *  r,g,b values are from 0 to 1
 *  h = [0,360], s = [0,1], v = [0,1]
 *  if s == 0, then h = -1 (undefined)
 *  使用方法:
 *      rgb2hsv(0.2,0.3,0.3,&x,&y,&z);
 */
void rgb2hsv(float R, float G, float B, float *H, float *S, float* V)
{
    float min, max, delta,tmp;
    tmp = R<G?R:G;
    min = tmp<B?tmp:B;
    tmp = R>G?R:G;
    max = tmp>B?tmp:B;
    *V = max; // v

    delta = max - min;

    if( max != 0 )
      *S = delta / max; // s
    else
    {
       // r = g = b = 0 // s = 0, v is undefined
      *S = 0;
      *H = -1;
      return;
    }
    if( R == max )
        *H = ( G - B ) / delta; // between yellow & magenta
   else if( G == max )
        *H = 2 + ( B - R ) / delta; // between cyan & yellow
   else
       *H = 4 + ( R - G ) / delta; // between magenta & cyan

    (*H) *= 60; // degrees
    if( *H < 0 )
       (*H) += 360;
}


/**
 *  hsv2rgb
 *  r,g,b values are from 0 to 1
 *  h = [0,360], s = [0,1], v = [0,1]
 *  if s == 0, then h = -1 (undefined)
 *  使用方法:
 *       hsv2rgb(60,0.3,0.5,&x,&y,&z);
*/
void hsv2rgb(float H, float S, float V, float *R, float *G, float *B)
{
     int i;
    float f, p, q, t;

    if( S == 0 )
    {
        *R =*G = *B = V;
        return;
    }

    H /= 60; // sector 0 to 5
    i = floor( H );
    f = H - i; // factorial part of h
    p = V * ( 1 - S );
    q = V * ( 1 - S * f );
    t = V * ( 1 - S * ( 1 - f ) );

    switch( i )
    {
    case 0:
        *R = V;
        *G = t;
        *B = p;
       break;
    case 1:
       *R = q;
       *G = V;
       *B = p;
       break;
    case 2:
       *R = p;
       *G = V;
       *B = t;
       break;
    case 3:
       *R = p;
       *G = q;
       *B = V;
       break;
    case 4:
       *R = t;
       *G = p;
       *B = V;
       break;
    default: // case 5:
       *R = V;
       *G = p;
       *B = q;
       break;
    }
}



/**
 * 直方图均衡化
 * 返回 0正确 -1错误
 */
int HistEqualization(Bitmap* dstBmp, Bitmap* srcBmp)
{
    return 0;
}

/*
 * 中值滤波 
*/


int MedFilt(Bitmap* dstBmp, Bitmap* srcBmp)
{
    return 0;
}



//平滑去噪

int smooth(Bitmap* src, Bitmap* dst)
{
    int ret;
    int n=0,i,j;
    int sum;

    //为dst图像分配数据空间
    ret=CreateBitmap(dst,src->width,src->height,8);
    if(ret==-1)
    {
        printf("Error(Gray2BW): can't create target image.\n");
        return -1;
    }

    for(i=1;i<src->height-1;i++)
    {
        for(j=1;j<src->width-1;j++)
        {   
            sum = 0;//clear sum
            sum+=*(src->imageData+src->widthStep*(src->height-1-i-1)+j-1);
            sum+=*(src->imageData+src->widthStep*(src->height-1-i-1)+j);
            sum+=*(src->imageData+src->widthStep*(src->height-1-i-1)+j+1);

            sum+=*(src->imageData+src->widthStep*(src->height-1-i)+j-1);
            sum+=*(src->imageData+src->widthStep*(src->height-1-i)+j);// 该点
            sum+=*(src->imageData+src->widthStep*(src->height-1-i)+j+1);

            sum+=*(src->imageData+src->widthStep*(src->height-1-i+1)+j-1);
            sum+=*(src->imageData+src->widthStep*(src->height-1-i+1)+j);
            sum+=*(src->imageData+src->widthStep*(src->height-1-i+1)+j+1);

            *(dst->imageData+dst->widthStep*(dst->height-1-i)+j)=(sum/9);//赋值给目标


        }
    }

    return 0;
}




//膨胀

int pengzhang(Bitmap* src, Bitmap* dst)
{
    int ret;
    int n=0,i,j;
    int r;

    //为dst图像分配数据空间
    ret=CreateBitmap(dst,src->width,src->height,8);
    if(ret==-1)
    {
        printf("Error(Gray2BW): can't create target image.\n");
        return -1;
    }

    for(i=1;i<src->height-1;i++)
    {
        for(j=1;j<src->width-1;j++)
        {   
            r=*(src->imageData+src->widthStep*(src->height-1-i)+j);     
            if(r==0)
            {
            *(dst->imageData+dst->widthStep*(dst->height-1-i-1)+j-1)=0;
            *(dst->imageData+dst->widthStep*(dst->height-1-i-1)+j)=0;
            *(dst->imageData+dst->widthStep*(dst->height-1-i-1)+j+1)=0;

            *(dst->imageData+dst->widthStep*(dst->height-1-i)+j-1)=0;
            *(dst->imageData+dst->widthStep*(dst->height-1-i)+j)=0;
            *(dst->imageData+dst->widthStep*(dst->height-1-i)+j+1)=0;

            *(dst->imageData+dst->widthStep*(dst->height-1-i+1)+j-1)=0;
            *(dst->imageData+dst->widthStep*(dst->height-1-i+1)+j)=0;
            *(dst->imageData+dst->widthStep*(dst->height-1-i+1)+j+1)=0;
            }
            else *(dst->imageData+dst->widthStep*(dst->height-1-i)+j)=r;
        }
    }

    return 0;
}







int fushi(Bitmap* src, Bitmap* dst)
{
    int ret;
    int n=0,i,j;
    int r,sum;

    //为dst图像分配数据空间
    ret=CreateBitmap(dst,src->width,src->height,8);
    if(ret==-1)
    {
        printf("Error(Gray2BW): can't create target image.\n");
        return -1;
    }

    for(i=1;i<src->height-1;i++)
    {
        for(j=1;j<src->width-1;j++)
        {   
            r=*(src->imageData+src->widthStep*(src->height-1-i)+j);     

            if(r==0)
            {
            sum = 0;//clear sum
            sum+=*(src->imageData+src->widthStep*(src->height-1-i-1)+j-1);
            sum+=*(src->imageData+src->widthStep*(src->height-1-i-1)+j);
            sum+=*(src->imageData+src->widthStep*(src->height-1-i-1)+j+1);

            sum+=*(src->imageData+src->widthStep*(src->height-1-i)+j-1);
            sum+=*(src->imageData+src->widthStep*(src->height-1-i)+j);// 该点
            sum+=*(src->imageData+src->widthStep*(src->height-1-i)+j+1);

            sum+=*(src->imageData+src->widthStep*(src->height-1-i+1)+j-1);
            sum+=*(src->imageData+src->widthStep*(src->height-1-i+1)+j);
            sum+=*(src->imageData+src->widthStep*(src->height-1-i+1)+j+1);
            if(sum>=255){
                *(dst->imageData+dst->widthStep*(dst->height-1-i)+j)=255;}
            else {*(dst->imageData+dst->widthStep*(dst->height-1-i)+j)=r;}
            }
            else *(dst->imageData+dst->widthStep*(dst->height-1-i)+j)=255;
        }
    }

    return 0;
}







int qufan(Bitmap* src, Bitmap* dst)
{
    int ret;
    int n=0,i,j;

    //为dst图像分配数据空间
    ret=CreateBitmap(dst,src->width,src->height,8);
    if(ret==-1)
    {
        printf("Error(Gray2BW): can't create target image.\n");
        return -1;
    }
    for(i=1;i<src->height-1;i++)
    {
        for(j=1;j<src->width-1;j++)
        {   

        *(dst->imageData+dst->widthStep*(dst->height-1-i)+j)=255-*(src->imageData+src->widthStep*(src->height-1-i)+j);
        }
    }

    return 0;
}

#endif /* BASICPROCESS_H_ */



效果图 中间过程图太多了,就不上了 这是最后的图。
这里写图片描述
废话不多说 直接show 代码 你们看吧。

2019-07-04 10:41:13 qq_28005905 阅读数 45
  • MATLAB基础知识大串讲

    Matlab基础知识大串讲,具体内容包括matlab下载安装、数据类型、矩阵操作、运算符、字符串处理、数组运算、M文件、变量、控制流、脚本与函数、图形绘制、二维图形绘制、三维图形绘制、四维图形绘制。

    32940 人正在学习 去看看 魏伟

Python语言不调用OpenCV函数实现任意模板滤波

编译环境

由于编程语言选择Python,所以博主用的编译器为PyCharm 2017

前提

岗萨勒斯第三版的数字图像处理中,介绍到空间滤波器模板,为了实现任意模板的滤波,例如3×3或5×5的均值滤波和3×3或5×5的高斯滤波,以及任意数值的空间滤波模板,用python语言在PyCharm中编写了如下代码。

代码

此次例中中采用的是5×5,sigma=1.4的高斯滤波模板,模板设置如下:
在这里插入图片描述
代码如下

import cv2
from pylab import *

def GeneralFilter(Image,a):           #输入图像Image,模板a
    im=array(Image)
    dim=math.sqrt(len(a))             # 模板的维度dim
    w=im.shape[0]                     # 计算输入图像的宽高
    h=im.shape[1]
    b=[]                              # 待处理的与模板等大小的图像块,BGR通道
    g=[]
    r=[]
    for i in range(int(dim/2),w-int(dim/2)):
        for j in range(int(dim/2),h-int(dim/2)):
            for m in range(-int(dim/2),-int(dim/2)+int(dim)):
                for n in range(-int(dim / 2), -int(dim / 2) + int(dim)):
                    b.append(im[i+m,j+n,0])
                    g.append(im[i+m,j+n,1])
                    r.append(im[i+m,j+n,2])
            im[i,j,0]=sum(np.multiply(np.array(a),np.array(b)))/sum(a)
            im[i, j, 1] =sum(np.multiply(np.array(a),np.array(g)))/sum(a)
            im[i, j, 2] =sum(np.multiply(np.array(a),np.array(r)))/sum(a)
            b=[];g=[];r=[]
    return im
img=cv2.imread('Gauss.jpg')
a=[2,4,5,4,2,4,9,12,9,4,5,12,15,12,5,4,9,12,9,4,2,4,5,4,2]
im=GeneralFilter(img,a)
cv2.imshow('Origin',img)
cv2.imshow('GaussFilter',im)
cv2.waitKey()
cv2.destroyAllWindows()

滤波结果如下

在这里插入图片描述

总结

高斯滤波对于被高斯噪声污染的图像有比较好的处理效果,而该模板同样可以设计成Sobel算子模板和其他的模板,具有很好的通用性,值得学习。

2019-11-08 12:21:58 qingfengxiaosong 阅读数 40
  • MATLAB基础知识大串讲

    Matlab基础知识大串讲,具体内容包括matlab下载安装、数据类型、矩阵操作、运算符、字符串处理、数组运算、M文件、变量、控制流、脚本与函数、图形绘制、二维图形绘制、三维图形绘制、四维图形绘制。

    32940 人正在学习 去看看 魏伟

目前在图像处理中有两种最重要的语言:c/c++matlab

它们各有优点:c/c++比较适合大型的工程,效率较高,而且容易转成硬件语言,是工业界的默认语言之一。而matlab实现起来比较方便,适用于算法的快速验证,而且matlab有成熟的工具箱可以使用,比如图像处理工具箱,信号处理工具箱。它们有一个共同的特点:开源的资源非常多。在学术界matlab使用的非常多,很多作者给出的源代码都是matlab版本。最近由于OpenCV的兴起和不断完善,c/c++在图像处理中的作用越来越大。总的来说,c/c++matlab都必须掌握,最好是精通,当然侧重在c/c++上对找工作会有很大帮助。

计算机视觉/图像算法/模式识别 工程师们使用的主流编程语言

 

1) 重中之重:编程语言之C/C++

公司面试除了考查应聘者的图像处理基础知识、思维逻辑和个人品性之外,在个人能力之中最重要的一条就是C/C 的功底,很多学生朋友们在学校求学阶段并不重视C/C++的学习,导致找工作时处处碰壁(不过对于来参加面试的朋友,如果有较强的逻辑思维或图像理论功底,即使C/C++ 功底弱些,企业还是会偏爱的,毕竟C/C++ 只是一个工具,只要给些时间去钻研还是可以调高的,但是逻辑思维能力和图像理论功底却不是短时期就能提高的。不过一般逻辑思维和图像理论比较强的人,其C/C 水平也是不错的)

 

为啥要这么重视C/C++ ?答案很简单,与绝大多数其它开发语言相比:C/C++ 的应用领域无法被超越、程序运行效率无法匹敌(当然汇编语言除外),是使用人数最多、跨平台最广的语言工具(适用于windows/linux/dsp/arm/单片机,当然还有其它一些平台)。简单的说,对于多数应用,其它语言能做的事情C/C++ 几乎都能做,其它语言不能做的事情C/C++ 也可以做。

 

2) 辅助工具之:MATLAB

百度百科中是这么说的:“MATLAB是美国MathWorks公司出品的商业数学软件,用于算法开发、数据可视化、数据分析以及数值计算的高级技术计算语言和交互式环境,主要包括MATLABSimulink两大部分。

 

MATLAB本身是一个不错的仿真、建模工具,但不适用于应用级项目的开发,原因很简单:效率与C/C++ 无法匹敌、不夸平台。(虽然后来出来了codegen可以将MATLAB部分代码转换为C++,但自动生成的还是无法与我们自己写的并优化的C++代码相比;还有MATLAB mex接口能够将C++MABLAB接口对接,既然使用了MATLAB编程,那在应用级的领域还是无法与纯C++相比)

 

 

 

对于企业,特别是私企,公司除非给你充足的时间先使用MATLAB做完算法功能,然后再用C/C++ 慢慢改写,而且了解的朋友们都知道,MATLAB的精度与封装的函数标准与C/C++ 有很多不一样,改写起来相对麻烦一些,这样太慢太慢太慢了,项目不等人啊。试问人家成手能够用短时间写出C/C++ 做图像算法并马上可以投入应用,而自己却在那边慢慢磨MATLAB,然后再费老大劲改成纯C(比如需要警觉MATLABC++精度不一样的问题、图像处理基础函数标准不一样的问题),那么老板会比较喜欢谁呢?

 

如果大家从最初就使用C/C++ ,虽然一开始不数量会写的很慢,但是随着知识量和自各种库(比如图像处理库)的积累,那么总有一天开发速度会快起来的,量的积累,质的飞跃。

 

说了不少,本人并不否认MATLABMATLAB做为建模、仿真以及一些验证的工作(比如图形分析和处理、图表显示、图像仿真、语音仿真等)还是不错的,这方面大嘴绝对力挺MATLAB,目前本人也还在使用中。

 

一句话:对于多数普通人来讲,如果你的目标是想进企业做为一个实力派工程师,那么大嘴建议您以C/C++ 为主、MATLAB为辅助工具做开发。

 

3) 辅助工具之:OPENCV

随着opencv的问世,图像算法/计算机视觉/模式识别行业的门槛儿变低了,原因有以下几点:(1)opencv是以C/C ++为基础开发出来的,适用性强,windows下适用opencv开发的图像算法应用效率足够快(2)封装了很多基础图像处理函数和视觉算法,可谓拿来即可用 (3)与嵌入式接口的统一趋势,如前几年大牛们人物搞出来的EMCV(基于C/C++ ),其基础架构和接口与opencv基本一致,但个人认为EMCV很多函数功能尚不完善,目前暂时无法与opencv相比。今后很多人在windows下基于opencv开发后,可以较为轻松的移植到DSP上,这种开发模式会是一种趋势。

 

说了opencv几条优点,但本人并不赞同只依赖opencv做开发,无论是图像算法行业还是其它很多行业,最重要的不是用什么工具,而是自己的基础知识和逻辑思维方式,opencv封装了很多基础函数,如果朋友们未搞懂其基础原理便加以使用,这种方式并不利于锻炼自己,抽空自己实现一下opencvMATLAB的封装好的那些基础函数吧,久而久之,你会发现自己站的高度会越来越高的。

说到这里,改写一下评述MATLAB时的一句话:对于多数普通人来讲,如果你的目标是想进企业做为一个实力派工程师,那么大嘴建议您以C/C ++为主、OPENCVMATLAB为辅助工具做开发。

 

4) 简单说说其它语言

其它开发语言,比如:C#,JAVA(还有很多很多语言,不一一举例了)都是不错的开发语言,各自有各自的主应用领域和优势,也有很多很多牛人在使用,不过做图像处理嘛,如果不偏向企业级应用(如嵌入式中),虽然也可以用,但是了解的朋友做出来的算法效率实在不敢恭维…,又无法夸平台,在一些不要求效率的场合还是可以用的,所以请学生朋友们慎重选择开发语言,因为这与自己以后的择业以及职位方向有很大关系。

2015-11-13 22:22:46 geekmanong 阅读数 3954
  • MATLAB基础知识大串讲

    Matlab基础知识大串讲,具体内容包括matlab下载安装、数据类型、矩阵操作、运算符、字符串处理、数组运算、M文件、变量、控制流、脚本与函数、图形绘制、二维图形绘制、三维图形绘制、四维图形绘制。

    32940 人正在学习 去看看 魏伟

MATLAB具有丰富的图像处理函数库,运算速度慢,特别是在多重循环的情况下,不适合直接应用于工程当中。如果能把MATLAB和另一种适合工程的编程语言结合到一起运用到数字图像处理领域,则会更加方便的进行图像处理,MATLAB和C/C++的混合编程,既继承了MATLAB的优点,又拥有了C/C++运算速度快、适合工程应用的特点。

一、MATLAB引擎与运行环境配置

1.MATLAB引擎

MATLAB引擎包含了所需要的运行库,允许C/C++来调用MATLAB内部的函数进行编程。MATLAB引擎是一种独立的C/C++程序,可以通过相应的接口在Windows系统上使用,是在一个单独的进程中运行的,不会拖慢主进程的运行速度。MATLAB引擎提供了一系列函数,允许用户在程序里启动或者结束调用MATLAB的进程,给MATLAB进程发送指令以及给MATLAB发送数据或者从MATLAB中得到数据。

通过MATLAB引擎,用户可以在C/C++程序中调用MATLAB内的数学处理函数,比如傅里叶变换函数,也可以通过plot函数进行绘图。

2.MATLAB引擎的重要函数

C/C++程序中使用MATLAB函数,首先要包含MATLAB引擎头文件engine.h, 只有这样,C/C++程序才能正确的识别MATLAB引擎函数。

(1)引擎的打开和关闭

Engine *engOpen(const char *startcmd);

参数 startcmd 是用来启动 Matlab 引擎的字符串参数,在 Windows 操作系统中只能为 NULL ,函数返回值是一个 Engine 类型的指针,它是在 engine.h 中定义的 engine 数据结构。

int engClose(Engine *ep);

参数 ep 代表要被关闭的引擎指针,函数返回值为 0 表示关闭成功,返回 1 表示发生错误。

例如,通常用来打开 / 关闭 Matlab 引擎的代码如下:

Engine *ep; // 定义 Matlab 引擎指针。 
if (!(ep=engOpen(NULL))) // 测试是否启动 Matlab 引擎成功。 
{
MessageBox("Can't start Matlab engine!" );
exit(1);
}
…………
engClose(ep); // 关闭 Matlab 引擎。

2)向 Matlab 发送命令字符串

engEvalString -发送命令让 Matlab 执行;

int engEvalString(Engine *ep, Const char *string);
参数 ep 为函数 engOpen 返回的引擎指针,字符串 string 为要 matlab 执行的命令,函数返回值为 0 表示成功执行,返回 1 说明执行失败(如命令不能被 Matlab 正确解释或 Matlab 引擎已经关闭了)。

(3)读写 Matlab 数据

从 Matlab 引擎工作空间中获取变量;

mxArray *engGetVariable(Engine *ep, const char *name);
参数 ep 为打开的 Matlab 引擎指针, mp 为指向被写入变量的指针, name 为变量写入后在 Matlab 引擎工作空间中的变量名,函数返回值为 0 表示写入变量成功,返回值为 1 表示发生错误。 

(4)创建和清除 mxArray 型数据

Matlab 有很多种变量类型,对应于每种类型,基本上都有一个函数用于创建,但它们都有相同的数据结构,就是 mxArray ,数组的建立采用mxCreatexxx 形式的函数,例如新建一个double 类型数组,可用函数mxCreateDoubleMatrix ,函数形式如下:

mxArray *mxCreateDoubleMatrix(int m, int n, mxComplexity ComplexFlag);
参数 m 和 n 为矩阵的函数和列数。 ComplexFlag 为常数,用来区分矩阵中元素是实数还是复数,取值分别为 mxREAL 和 mxCOMPLEX 。 

例如,创建一个 3 行 5 列的二维实数数组,可用如下语句:

mxArray *T = mxCreateDoubleMatrix(3, 5, mxREAL);
对应的,要删除一个数组mxDestroyArray ,该函数声明如下:

void mxDestroyArray(mxArray *array_ptr);
参数 array_ptr 为要删除的数组指针;

要删除上面创建的数组 T ,可用如下语句:

mxDestroyArray(T);
创建一个字符串类型并初始化为 str 字符串:

mxArray *mxCreateString(const char *str);







2019-10-30 20:18:50 sd4567855 阅读数 102
  • MATLAB基础知识大串讲

    Matlab基础知识大串讲,具体内容包括matlab下载安装、数据类型、矩阵操作、运算符、字符串处理、数组运算、M文件、变量、控制流、脚本与函数、图形绘制、二维图形绘制、三维图形绘制、四维图形绘制。

    32940 人正在学习 去看看 魏伟

自然语言与编程语言

  1. 自然语言中词汇比编程语言中词汇丰富。
  2. 自然语言是非结构化,编程语言是结构化的。结构化:信息具有明确的结构关系。
  3. 自然语言含有大量歧义。
  4. 容错性。
  5. 易变性。
  6. 简略性。

自然语言处理层次

  1. 语音、图像、文本,其中文本是重中之重。
  2. 词法分析:将文本分割为有意义的词语(中文分词),确定每个词语的类别和浅层的歧义消除(词性标注),识别出专有名词(命名实体识别)。
  3. 信息抽取。
  4. 文本分类、文本聚类。
  5. 句法分析。
  6. 语义分析:确定一个词在语境中的含义,而不是词性(词义消除),标注句子中的谓语和其他成分的关系(语义角色标注),分析句子中词语之间的语义关系(语义依存分析)。

自然语言处理的流派

  1. 基于规则的专家系统
  2. 基于统计的学习方法
  3. 传统方法与深度学习

机器学习

  1. 模型:被学习的算法。
  2. 特征。
  3. 数据集/语料库。
  4. 监督学习。
  5. 无监督学习。
  6. 半监督学习。

语料库

  1. 中文分词语料库
  2. 词性标注语料库
  3. 命名实体识别语料库
  4. 词法分析语料库
  5. 文本分类语料库

图像处理入门教程

阅读数 30190

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