惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

H
Help Net Security
博客园 - Franky
GbyAI
GbyAI
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
爱范儿
爱范儿
IT之家
IT之家
酷 壳 – CoolShell
酷 壳 – CoolShell
aimingoo的专栏
aimingoo的专栏
博客园_首页
MongoDB | Blog
MongoDB | Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Recent Announcements
Recent Announcements
Scott Helme
Scott Helme
有赞技术团队
有赞技术团队
M
MIT News - Artificial intelligence
C
CERT Recently Published Vulnerability Notes
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Jina AI
Jina AI
F
Fortinet All Blogs
N
Netflix TechBlog - Medium
L
LangChain Blog
L
LINUX DO - 最新话题
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
H
Hacker News: Front Page
MyScale Blog
MyScale Blog
P
Palo Alto Networks Blog
G
Google Developers Blog
Google DeepMind News
Google DeepMind News
AI
AI
T
Troy Hunt's Blog
Microsoft Azure Blog
Microsoft Azure Blog
阮一峰的网络日志
阮一峰的网络日志
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Vercel News
Vercel News
Microsoft Security Blog
Microsoft Security Blog
罗磊的独立博客
S
Secure Thoughts
大猫的无限游戏
大猫的无限游戏
博客园 - 叶小钗
人人都是产品经理
人人都是产品经理
Blog — PlanetScale
Blog — PlanetScale
博客园 - 司徒正美
Apple Machine Learning Research
Apple Machine Learning Research
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 三生石上(FineUI控件)
S
Security @ Cisco Blogs
Cloudbric
Cloudbric
E
Exploit-DB.com RSS Feed
Attack and Defense Labs
Attack and Defense Labs

博客园 - 跌跌撞撞

CArchive的一个经验 设计Client 加载COM的方式 学习反汇编记录 299错误解决记录 23日记录 用ADO访问存储过程的参数问题 SDKMisc的一个小错误 年初一作诗 走出GDI 总是在最求效率。 新感 下来做什么呢 开发目录包括的内容 太可爱的小小播放器 lucene的设计 上海感觉 写一点感想 项目管理的成功秘密(翻译)
昨天看书的心得
跌跌撞撞 · 2005-03-30 · via 博客园 - 跌跌撞撞

昨天做图像算法,总觉得YIQ色彩和RGB之间通过相互转换就能得到颜色的灰度值。
如果得到一个RGB的灰度值,就能进行灰度变换。图像增强基本都是基于灰度做出来的。

 void RGB2YIQ(REAL *y, REAL *i, REAL*q, BYTE r, BYTE g, BYTE b);
 void YIQ2RGB(BYTE *r, BYTE *g, BYTE *b, REAL y, REAL i, REAL q);

REAL RGB2YIQMat[3][3] =
        {{ 0.30f,  0.59f,  0.11f},
         { 0.60f, -0.28f, -0.32f},
         { 0.21f, -0.52f,  0.31f}};

REAL YIQ2RGBMat[3][3] = 
        {{ 1.0000f,  0.9483f,  0.6240f},
         { 1.0000f, -0.2761f, -0.6398f},
         { 1.0000f, -1.1055f,  1.7299f}};


/*Converts r, g, b, into y, i, q*/
void CImpactPlus::RGB2YIQ(REAL *y, REAL *i, REAL*q, BYTE r, BYTE g, BYTE b)
{
    REAL rT, gT, bT;
    rT = r / 255.0f; gT = g / 255.0f; bT = b / 255.0f;

    *y = RGB2YIQMat[0][0] * rT + RGB2YIQMat[0][1] * gT + RGB2YIQMat[0][2] * bT; 
    *i = RGB2YIQMat[1][0] * rT + RGB2YIQMat[1][1] * gT + RGB2YIQMat[1][2] * bT; 
    *q = RGB2YIQMat[2][0] * rT + RGB2YIQMat[2][1] * gT + RGB2YIQMat[2][2] * bT;

    *i = (*i + 0.6f) / 1.2f;
    *q = (*q + 0.52f) / 1.04f;


    if (*y < 0.0) *y = 0.0f;
    if (*y > 1.0) *y = 1.0f;
    if (*i < 0.0) *i = 0.0f;
    if (*i > 1.0) *i = 1.0f;
    if (*q < 0.0) *q = 0.0f;
    if (*q > 1.0) *q = 1.0f;
}


/*Converts y, i, q, into r, g, b*/
void CImpactPlus::YIQ2RGB(BYTE *r, BYTE *g, BYTE *b, REAL y, REAL i, REAL q)
{
    REAL rT, gT, bT;

    i = i * 1.2f - 0.6f;
    q = q * 1.04f - 0.52f;

    rT = YIQ2RGBMat[0][0] * y + YIQ2RGBMat[0][1] * i + YIQ2RGBMat[0][2] * q; 
    gT = YIQ2RGBMat[1][0] * y + YIQ2RGBMat[1][1] * i + YIQ2RGBMat[1][2] * q; 
    bT = YIQ2RGBMat[2][0] * y + YIQ2RGBMat[2][1] * i + YIQ2RGBMat[2][2] * q;


    if (rT < 0.0f) rT = 0.0f;
    if (rT > 1.0f) rT = 1.0f;
    if (gT < 0.0f) gT = 0.0f;
    if (gT > 1.0f) gT = 1.0f;
    if (bT < 0.0f) bT = 0.0f;
    if (bT > 1.0f) bT = 1.0f;

    *r = max(0, min(255, (BYTE)(rT * 255.0f)));
    *g = max(0, min(255, (BYTE)(gT * 255.0f)));
    *b = max(0, min(255, (BYTE)(bT * 255.0f)));

}

在数字图像处理的书中,经常有这样的程序:

  PixelValue = (BYTE)(0.299*(float)lpDIBBits[p+2] + 0.587*(float)lpDIBBits[p+1]+0.114*(float)lpDIBBits[p]+0.1;

这行程序的意思是:得到当前像素的YIQ之Y值。
而lpDIBBits[p+2]就是红色成分, lpDIBBits[p+1]是绿色成分, lpDIBBits[p]是蓝色成分。
唯一不明白的是他为什么要加0.1?

下面是我依照他的原理来实现图像的线性灰度变换。

Status CImpactPlus::LinerTrans(Bitmap* pBitmap, float fa, float fb)
{
 Status s;
 TestGdiPointer(_T("HistogramEqual"), pBitmap);
 
 

 INT nWidth = pBitmap->GetWidth();
 INT nHeight = pBitmap->GetHeight();

 BitmapData bitmapData;

 Rect rt(0, 0, nWidth, nHeight);

 if(StatusBad(s = pBitmap->LockBits(&rt,
  ImageLockModeRead | ImageLockModeWrite,
  PixelFormat32bppARGB, &bitmapData)))
 

 return SGTRACE_ERR(_T("LockBits"), s);

 ARGB* pixels = (ARGB*)bitmapData.Scan0;

 
 float fy, fi, fq;
 fy = fi = fq = 0.0f;
 BYTE a, r, g, b;
 for(int row=rt.Y; row<rt.Height; row++)
 {
  for(int col=rt.X; col<rt.Width; col++)
  {
   ARGB c = pixels[row * bitmapData.Stride / 4 + col];
   Color color(c);
   a = color.GetA();
   r = color.GetR();
   g = color.GetG();
   b = color.GetB();
   
   RGB2YIQ(&fy, &fi, &fq, r, g, b);
   float fTemp = fa * fy + fb;
   YIQ2RGB(&r, &g, &b, fTemp, fi, fq);
   
   pixels[row * bitmapData.Stride / 4 + col] = color.MakeARGB(a,r,g,b);
  }
 }

 if(StatusBad(s = pBitmap->UnlockBits(&bitmapData)))
  return SGTRACE_ERR(_T("UnlockBits"), s);

 return Ok;
}

这样方法简单明快,即使是很复杂的算法,实现起来也很清晰。