MSDN的代码

  1. COLORREF pixel;
  2. int maxY = imgOriginal.GetHeight(), maxX = imgOriginal.GetWidth();
  3. byte r,g,b,avg;
  4. for (int y=0; y<maxY; y++) {
  5. for (int x=0; x<maxX; x++) {
  6. pixel = imgOriginal.GetPixel(x,y);
  7. r = GetRValue(pixel);
  8. g = GetGValue(pixel);
  9. b = GetBValue(pixel);
  10. avg = (r+ g+ b)/3;
  11. imgOriginal.SetPixelRGB(x,y,avg,avg,avg);
  12. }}

这种方式效率很低, 因为每次调用getpixel,都包含着程序的进栈和出栈。所以,面对大量需要处理的数据,采用直接访问内存地址的方法。

  1. byte* pRealData;
  2. pRealData=(byte*)imgOriginal.GetBits();
  3. int pit=imgOriginal.GetPitch();
  4. int bitCount=imgOriginal.GetBPP()/8;
  5. for (int y=0; y<maxY; y++) {
  6. for (int x=0; x<maxX; x++) {
  7. int grayVal=(int)(int)(*(pRealData + pit*y + x*bitCount))*0.3
  8. + (int)(int)(*(pRealData + pit*y + x*bitCount +1))*0.59
  9. + (int)(int)(*(pRealData + pit*y + x*bitCount +2))*0.11;
  10. *(pRealData + pit*y + x*bitCount)=grayVal;
  11. *(pRealData + pit*y + x*bitCount +1)=grayVal;
  12. *(pRealData + pit*y + x*bitCount +2)=grayVal;
  13. //如果是8位灰度图像,直接读取一个BYTE位为灰度值
  14. //如果是24位RGB图像,则依次读取pixAddr,pixAddr+1,pixAddr+2为B、G、R分量值
  15. }}

用两种方法对同一张图片(3264*2448像素)进行处理,前者需要1分钟,后者只需1秒左右。

所以,后者比前者至少快60倍

直接访问内存地址的另一种方式:

        int i,j,temp;
int pixel[4];
int width = yuantu.GetWidth();
int height = yuantu.GetHeight();
int widthBytes = yuantu.GetPitch();
bianyuantu.Create(width,height,yuantu.GetBPP()); if(yuantu.IsIndexed())
{
yuantu.GetColorTable(0,256,colorTable);
bianyuantu.SetColorTable(0,256,colorTable);
}
BYTE *pYuantuData = (BYTE*)yuantu.GetBits();
BYTE *pBianyuantuData =(BYTE*)bianyuantu.GetBits(); for(j=0;j<height-1;j++)
{
for(i=0;i<width-1;i++)
{
pixel[0]=pYuantuData[j*widthBytes+i];
pixel[1]=pYuantuData[j*widthBytes+i+1];
pixel[2]=pYuantuData[(j+1)*widthBytes+i];
pixel[3]=pYuantuData[(j+1)*widthBytes+i+1];
temp=(int)sqrt((double)((pixel[0]-pixel[3])*(pixel[0]-pixel[3])
+(pixel[1]-pixel[2])*(pixel[1]-pixel[2]))); //罗伯特算子
pBianyuantuData[j*widthBytes+i]=temp;
}
}

  

彩色图像转化为灰度图的处理方式

//真彩色图像变为灰度图,直接修改像素点的值

  1. void PixelsChangedToGray(CImage *pImage)
  2. {
  3. int  nByte,j,i,nWidth,nHeight,nBytesPerPixel;
  4. BYTE  *pPixelLine,cNewPixelValue;
  5. nWidth=pImage->GetWidth();   nHeight=pImage->GetHeight();
  6. nBytesPerPixel= pImage->GetBPP()/8;
  7. for (i=0;i<nHeight;i++){
  8. pPixelLine =(BYTE*) pImage->GetPixelAddress(0,i);
  9. nByte=0;
  10. for (j=0;j<nWidth;j++){      cNewPixelValue=(BYTE)(0.11*pPixelLine[nByte]
  11. +0.59*pPixelLine[nByte+1]
  12. +0.30*pPixelLine[nByte+2]);
  13. pPixelLine[nByte] = pPixelLine[nByte+1] = pPixelLine[nByte+2]
  14. = cNewPixelValue;
  15. nByte+=nBytesPerPixel;
  16. }
  17. }
  18. }

//非真彩色图像变为灰度图,修改调色板信息

  1. void PaletteChangedToGray(CImage *pImage)
  2. {
  3. RGBQUAD  ColorTabs[256];
  4. int  i,nColorTableEntries,nNewGrayColor;
  5. nColorTableEntries=pImage->GetMaxColorTableEntries();
  6. pImage->GetColorTable(0,nColorTableEntries,ColorTabs);
  7. for (i=0;i<nColorTableEntries;i++){
  8. nNewGrayColor=(int)(0.11*ColorTabs[i].rgbBlue
  9. + 0.59*ColorTabs[i].rgbGreen
  10. + 0.30*ColorTabs[i].rgbRed);
  11. ColorTabs[i].rgbBlue = (BYTE)nNewGrayColor;
  12. ColorTabs[i].rgbGreen = (BYTE)nNewGrayColor;
  13. ColorTabs[i].rgbRed = (BYTE)nNewGrayColor;
  14. }
  15. pImage->SetColorTable(0,nColorTableEntries,ColorTabs);
  16. }

CImage访问像素及其像素操作总结的更多相关文章

  1. OpenCV(2)-Mat数据结构及访问Mat中像素

    Mat数据结构 一开始OpenCV是基于C语言的,在比较早的教材例如<学习OpenCV>中,讲解的存储图像的数据结构还是IplImage,这样需要手动管理内存.现在存储图像的基本数据结构是 ...

  2. SNMP 原理及配置简述 net-snmp-utils net-snmp 第2版基于SNMP 群体名(community name) 第3版引入了安全性更高的访问控制方法 SNMP协议操作只有4种 Apache的php_snmp 模块

    SNMP 原理及配置简述  net-snmp-utils  net-snmp 第2版基于SNMP 群体名(community name) 第3版引入了安全性更高的访问控制方法 SNMP协议操作只有4种 ...

  3. C# 委托 / 跨线程访问UI / 线程间操作无效: 从不是创建控件“Form1”的线程访问它

    C# 委托 / 跨线程访问UI /  线程间操作无效: 从不是创建控件“Form1”的线程访问它 网上的代码都比较复杂,还是这个简单 见代码, 简易解决办法: 主窗体代码 using System; ...

  4. ADO.NET访问Access(文本数据库)数据操作(CRUD)

    1,ADO.NET访问Access(文本数据库)数据操作(CRUD) 2,DatabaseDesign 文本数据库Northwind.mdb 3,/App_Code 3.1,/App_Code/DBC ...

  5. GG_DataAccess 数据库访问层使用dapper操作

    3.5.GG_DataAccess 数据库访问层使用dapper操作 和Model实体类同理,tt模板已写好,需要的可加qq群:547765059  自己下载.

  6. 《OpenCV3编程入门》访问图像中像素的三类方法

    ·方法一 指针访问:C操作符[ ]; ·方法二 迭代器iterator; ·方法三 动态地址计算; #include <opencv2/core/core.hpp> #include &l ...

  7. 通过一个小Trick实现shader的像素识别/统计操作

    2018/12/14日补充:后来发现compute shader里用AppendStructuredBuffer可以解决这类问题,请看这里:https://www.cnblogs.com/hont/p ...

  8. opencv 中对一个像素的rgb值或像素值进行操作的几个常用小办法【转】

    You can access the Image pixels in many ways:1. One using the Inbuilt macro2. One using the pointer ...

  9. OpenCV 学习笔记(11)像素级别指针操作

    //优化两图的连接处,使得拼接自然 void OptimizeSeam(Mat& img1, Mat& trans, Mat& dst) { int start = MIN(c ...

随机推荐

  1. 通过 :hover 伪元素控制其他元素

    ---代码 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <tit ...

  2. Python: PS 图像调整--饱和度调整

    本文用 Python 实现 PS 图像调整中的饱和度调整算法,具体的算法原理和效果可以参考之前的博客: http://blog.csdn.net/matrix_space/article/detail ...

  3. Java 高阶 —— 相等性比较

    1. 包装类 所有的相同类型的包装类对象之间的值的比较,全部使用 equals 方法: 对于 Integer a = ?,在 -128 到 127 范围内的赋值,Integer 对象是在 Intege ...

  4. 「LuoguP3376」 【模板】网络最大流

    题目描述 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. 输入输出格式 输入格式: 第一行包含四个正整数N.M.S.T,分别表示点的个数.有向边的个数.源点序号.汇点序号. 接下来M行每行 ...

  5. 前端调用后端接口返回200(成功状态码),后端有返回,但是控制台Network Response为空,没展示任何信息

    解决方法: 1.在js里面debugger,可以看到后台是否有返回数据. 2.直接console.log(),直接把返回值打印出来,查看返回的数据格式,方便前端进行数据的处理. PS:因为后端返回的数 ...

  6. Linux查看CPU《型号..》《内存..》《硬盘..》《系统..》

    1.查看物理cpu个数 grep 'physical id' /proc/cpuinfo | sort -u | wc -l 2.查看核心数量grep 'core id' /proc/cpuinfo ...

  7. layui 复选框checkbox 全选写法

    前语:本来我是不想写layui框架的博客的,有的时候数据经过layui渲染后原生的写法就取不到值了,一定要用它框架的写法,实在蛋疼,故写之,以后用到可以省点时间去度娘! HTML: <div i ...

  8. ubuntu下使用锐捷校园网

    前言           以下内容是个人学习之后的感悟,转载请注明出处~ 1.首先下载锐捷Linux版本,然后解压缩后,有个rjsupplicant.sh这个脚本文件,于是按照README做了,终端中 ...

  9. Python之线程与GIL

    前言            以下内容是个人学习之后的感悟,转载请注明出处~ 线程是什么 线程是程序中一个单一的顺序控制流程.进程内一个相对独立的.可调度的执行单元,是系统独立调度和分派CPU的 基本单 ...

  10. <正则吃饺子> :关于新项目的环境搭建(一)

    来到新的公司,需要使用myeclipse.maven.svn.tomcat.mysql: 对于先前一直只用 netbeans 的我,在这里把环境搭建 的情况记录下来.来加深自己的学习和帮助后来者. 第 ...