关于统计变换(CT/MCT/RMCT)算法的学习和实现
原文地址http://blog.sina.com.cn/s/blog_684c8d630100turx.html
| 123 | 127 | 129 |
| 126 | 128 | 129 |
| 127 | 131 | 130 |
| 1 | 1 | 0 |
| 1 | 0 | |
| 1 | 0 | 0 |
然后,把此窗口结果组成一个序列:11010100,以此二进制序列表示的值来代替原图像窗口中心点的像素。如此下去,等到窗口滑动完整幅图像,我们就得到原图像做统计变换(CT)之后的图像。
- % *************************************************************************
- % Title: Function-Census Transform of a given Image
- % Author: Siddhant Ahuja
- % Created: May 2008
- % Copyright Siddhant Ahuja, 2008
- % Inputs: Image (var: inputImage), Window size assuming square window (var:
- % windowSize) of 3x3 or 5x5 only.
- % Outputs: Census Tranformed Image (var: censusTransformedImage),
- % Time taken (var: timeTaken)
- % Example Usage of Function: [a,b]=funcCensusOneImage('Img.png', 3)
- % *************************************************************************
- function [censusTransformedImage, timeTaken] = funcCensusOneImage(inputImage, windowSize)
- % Grab the image information (metadata) using the function imfinfo
- try
- imageInfo = imfinfo(inputImage);
- % Since Census Transform is applied on a grayscale image, determine if the
- % input image is already in grayscale or color
- if(getfield(imageInfo,'ColorType')=='truecolor')
- % Read an image using imread function, convert from RGB color space to
- % grayscale using rgb2gray function and assign it to variable inputImage
- inputImage=rgb2gray(imread(inputImage));
- else if(getfield(imageInfo,'ColorType')=='grayscale')
- % If the image is already in grayscale, then just read it.
- inputImage=imread(inputImage);
- else
- error('The Color Type of Input Image is not acceptable. Acceptable color types are truecolor or grayscale.');
- end
- end
- catch
- inputImage = inputImage;
- end
- % Find the size (columns and rows) of the image and assign the rows to
- % variable nr, and columns to variable nc
- [nr,nc] = size(inputImage);
- % Check the size of window to see if it is an odd number.
- if (mod(windowSize,2)==0)
- error('The window size must be an odd number.');
- end
- if (windowSize==3)
- bits=uint8(0);
- % Create an image of size nr and nc, fill it with zeros and assign
- % it to variable censusTransformedImage of type uint8
- censusTransformedImage=uint8(zeros(nr,nc));
- else if (windowSize==5)
- bits=uint32(0);
- % Create an image of size nr and nc, fill it with zeros and assign
- % it to variable censusTransformedImage of type uint32
- censusTransformedImage=uint32(zeros(nr,nc));
- else
- error('The size of the window is not acceptable. Just 3x3 and 5x5 windows are acceptable.');
- end
- end
- % Initialize the timer to calculate the time consumed.
- tic;
- % Find out how many rows and columns are to the left/right/up/down of the
- % central pixel
- C= (windowSize-1)/2;
- for j=C+1:1:nc-C % Go through all the columns in an image (minus C at the borders)
- for i=C+1:1:nr-C % Go through all the rows in an image (minus C at the borders)
- census = 0; % Initialize default census to 0
- for a=-C:1:C % Within the square window, go through all the rows
- for b=-C:1:C % Within the square window, go through all the columns
- if (~(a==0 && b==0)) % Exclude the centre pixel from the calculation,原来是(C+1),现改为0
- census=bitshift(census,1); %Shift the bits to the left by 1
- % If the intensity of the neighboring pixel is less than
- % that of the central pixel, then add one to the bit
- % string
- if (inputImage(i+a,j+b) < inputImage(i,j))
- census=census+1;
- end
- end
- end
- end
- % Assign the census bit string value to the pixel in imgTemp
- censusTransformedImage(i,j) = census;
- end
- end
- % Stop the timer to calculate the time consumed.
- timeTaken=toc;
| 1 | 1 | 0 |
| 1 | 0 | 0 |
| 1 | 0 | 0 |
对应的二进制序列为:110100100。然后以此作为中心像素点的像素值,循环完毕之后便得到MCT之后的图像。需要注意的一点是,如果要使变换之后的图像得到显示,应该对像素值做一下归一化,使其在0——255之间。
- #include "stdafx.h"
- #include "MCT.h"
- #include "highgui.h"
- MCT::MCT()
- {
- window_size = 0;
- }
- MCT::~MCT()
- {
- }
- void MCT::ModifiedCensusTransform(IplImage *input_image, IplImage *mct_image, const int window_size, const int delta )
- {
- CvSize image_size = cvGetSize(input_image);
- int image_width = image_size.width;
- int image_height = image_size.height;
- IplImage *gray_image = cvCreateImage(cvGetSize(input_image), input_image->depth, 1);
- cvSetZero(gray_image);
- if(input_image->nChannels != 1)
- {
- cvCvtColor(input_image, gray_image, CV_RGB2GRAY);
- }
- else
- {
- cvCopy(input_image, gray_image);
- }
- IplImage *modified_image = NULL;
- switch (window_size)
- {
- case 3:
- modified_image = cvCreateImage(image_size, IPL_DEPTH_16U, 1);
- cvSetZero(modified_image);
- break;
- case 5:
- modified_image = cvCreateImage(image_size, IPL_DEPTH_32S, 1);
- cvSetZero(modified_image);
- break;
- default:
- printf("window size must be 3 or 5!\n");
- exit(EXIT_FAILURE);
- }
- CvMat window;
- for(int i = 0; i < image_height - window_size; i++)
- {
- for(int j = 0; j < image_width - window_size; j++)
- {
- unsigned long census = 0;
- CvRect roi = cvRect(j, i, window_size, window_size);
- cvGetSubRect(gray_image, &window, roi);
- CvScalar m = cvAvg(&window, NULL);
- for(int w = 0; w < window_size; w++)
- {
- for(int h = 0; h < window_size; h++)
- {
- census = census << 1; //左移1位
- double tempvalue = cvGetReal2D(&window, w, h);
- if(tempvalue < m.val[0] + delta)
- census += 1;
- }
- }
- cvSetReal2D(modified_image, i, j, census);
- }
- }
- //cvConvertScaleAbs(modified_image, mct_image, 1, 0);
- Normalize(modified_image, mct_image);
- cvReleaseImage(&gray_image);
- cvReleaseImage(&modified_image);
- }
- void MCT::Normalize(IplImage *mct_image, IplImage *nor_image)
- {
- double minv, maxv;
- cvMinMaxLoc(mct_image, &minv, &maxv);
- for (int i = 0; i < mct_image->height; i++)
- {
- for (int j = 0; j < mct_image->width; j++)
- {
- double tempv = cvGetReal2D(mct_image, i, j);
- tempv = (tempv - minv) / (maxv - minv) * 255;
- cvSetReal2D(nor_image, i, j, tempv);
- }
- }
- }
由于算法比较简单,所以没有写注释,应该比较容易理解。
关于统计变换(CT/MCT/RMCT)算法的学习和实现的更多相关文章
- 肺结节CT影像特征提取(二)——肺结节CT图像特征提取算法描述
摘自本人毕业论文<肺结节CT影像特征提取算法研究> 医学图像特征提取可以认为是基于图像内容提取必要特征,医学图像中需要什么特征基于研究需要,提取合适的特征.相对来说,医学图像特征提取要求更 ...
- NLP之统计句法分析(PCFG+CYK算法)
一.认识句法分析 首先,了解一下句法分析到底是什么意思?是做什么事情呢?顾名思义,感觉是学习英语时候讲的各种句法语法.没错!这里就是把句法分析过程交给计算机处理,让它分析一个句子的句法组成,然后更好理 ...
- 推荐一个算法编程学习中文社区-51NOD【算法分级,支持多语言,可在线编译】
最近偶尔发现一个算法编程学习的论坛,刚开始有点好奇,也只是注册了一下.最近有时间好好研究了一下,的确非常赞,所以推荐给大家.功能和介绍看下面介绍吧.首页的标题很给劲,很纯粹的Coding社区....虽 ...
- 算法导论学习---红黑树具体解释之插入(C语言实现)
前面我们学习二叉搜索树的时候发如今一些情况下其高度不是非常均匀,甚至有时候会退化成一条长链,所以我们引用一些"平衡"的二叉搜索树.红黑树就是一种"平衡"的二叉搜 ...
- 【树论 1】 prim算法的学习和使用
进阶版神犇可以看看本题解的姊妹篇 Kruskal算法的学习和使用 下面的内容是prim算法 但是最小生成树是什么呢? 标准定义如下:在边子集所构成的树中,不但包括了连通图里的所有顶点,且其所有边的权值 ...
- 毕业设计预习:SM3密码杂凑算法基础学习
SM3密码杂凑算法基础学习 术语与定义 1 比特串bit string 由0和1组成的二进制数字序列. 2 大端big-endian 数据在内存中的一种表示格式,规定左边为高有效位,右边为低有效位.数 ...
- 第八模块:算法&设计模式、企业应用 第1章 常用算法&设计模式学习
第八模块:算法&设计模式.企业应用 第1章 常用算法&设计模式学习
- leetcode 刷500道题,笔试/面试稳过吗?谈一谈这些年来算法的学习
想要学习算法.应付笔试或者应付面试手撕算法题,相信大部分人都会去刷 Leetcode,有读者问?如果我在 leetcode 坚持刷它个 500 道题,以后笔试/面试稳吗? 这里我说下我的个人看法,我认 ...
- 【中国象棋人机对战】引入了AI算法,学习低代码和高代码如何混编并互相调用
以低代码和高代码(原生JS代码)混编的方式引入了AI算法,学习如何使用表达式调用原生代码的.整个过程在众触低代码应用平台进行,适合高阶学员. AI智能级别演示 AI算法分三个等级,体现出来的智能水平不 ...
随机推荐
- 用Qt写软件系列四:定制个性化系统托盘菜单
导读 一款流行的软件,往往会在功能渐趋完善的时候,通过改善交互界面来提高用户体验.毕竟,就算再牛逼的产品,躲藏在糟糕的用户界面之后总会让用户心生不满.界面设计需综合考虑审美学.心理学.设计学等多因素, ...
- [迷宫中的算法实践]迷宫生成算法——递归分割算法
Recursive division method Mazes can be created with recursive division, an algorithm which wo ...
- Java概述之从源码到运行
Java体系结构包括以下四个部分: 1. Java语言 2. Java class文件格式(被编译后的java类文件格式) 3. Java API 4. Java虚拟机JVM 它们之间的关系,总结一句 ...
- 那些教程没有的php1-基础知识补漏
php.net 字符串 heredoc结构 类似双引号,其中的变量会被解析.严格遵循下边的格式,结束标识符这行除了可能有一个分号(;)外,绝对不能包含其它字符. <?php $str = < ...
- SQL数据库基础(二)
数据类型: --类似于C#中的数据类型 Datetime 范围是:1753.1.1—— 9999.12.31 Smalldatetime 1900.1.1 ——2079.6.6 操作: ...
- Android 身份证号码查询、手机号码查询、天气查询
1.基本信息 身份证号码查询:http://apistore.baidu.com/apiworks/servicedetail/113.html 手机号码:http://apistore.baidu. ...
- ListView嵌套出现的问题
项目中一个列表子项中也需要用到列表,这就不由得使我想到ListView的嵌套,其实这个东西想想也只是复杂了一点,并没有什么难的地方,可是却依然在这里狠狠滴栽个跟头.问题出在子列表动态展开的操作上.可能 ...
- OC中结构体作为对象属性
在OC中结构体有时候也作为对象的属性 类的定义 #import <Foundation/Foundation.h> typedef struct{ int year; int month; ...
- iOS实现三屏复用循环广告[从服务器请求的广告]
循环广告我们在开发中已经是熟得不能再熟了,今天整理这篇scrollview三屏复用广告 原理使用scrollview里的三个imageview分别去加载不同的图片,用少量的资源来显示大量或不确定的广告 ...
- redis高可用之REDIS SENTINEL
1. Redis主从配置 1.1. 设置主从复制 Master <= Salve 10.24.6.5:6379 <= 10.24.6.7:6379 1.2. 取消主从复制 1.3. ...