2014-03-26 21:19:49 Linoi 阅读数 3934

专栏地址:http://blog.csdn.net/column/details/imagep.html

本系列博客主要记录Image_Lin图像处理软件的开发记录。

Image_Lin软件计划实现的功能包括:

(一)、基本图像处理(黑白、锐化、柔化、补光)

(二)、人像美容(人脸美肤)

(三)、图像特效(素描、油画、浮雕、怀旧、Lomo)

(四)、图像去雾

Image_Lin图像处理的开发工具是:QT+OpenCV


这一篇博客我主要对QT和OpenCV进行一个简单的介绍。


QT是一个跨平台的C++图形用户界面应用程序框架,首度为公众可用是在1995年5月。它最初由Haavard Nord和Eirik Chambe-Eng开发而成。当前最新的版本是Qt5.2,下载地址

一些关于QT的教程如下:

QT 编程基础入门到精通

Qt 学习之路 2

QT 学 习 

下面,我谈谈Qt的元对象系统

Qt的主要成就之一就是使用了一种机制对C++进行了扩展,并且使用这种机制创建了独立的软件组件。这些组件可以绑定在一起,但任何一个组件对于它所要连接的组件的情况事先一无所知。

这种机制称为元对象系统(meta-object system),它提供了关键的两项技术:信号-槽以及内省(introspection)。内省功能对于实现信号与槽是必需的,并且允许应用程序的开发人员在运行时获得有关QObject子类的“元信息”,包括一个含有对象的类名以及它所支持的信号和槽的列表。这一机制也支持属性和文本翻译,并且它也为QtScript模块奠定了基础。从Qt4.2开始,可以动态添加属性。

标准C++没有对Qt的元对象系统所需要的动态元信息提供支持。Qt通过提供一个独立的moc工具解决了这个问题,moc解析Q_OBJECT类的定义并且通过C++函数提供可供使用的信息。由于moc使用纯C++来实现它的所有功能,所以Qt的元对象系统可以在任意C++编译器上工作。

这一机制是这样工作的:

  • Q_OBJECT宏声明了在每一个QObject子类中必须实现的一些内省函数:metaObject()、tr()、qt_metacall(),以及其他一些函数。
  • Qt的moc工具生成了用于由Q_OBJECT声明的所有函数和所有信号的实现。
  • 像connect()和disconnect()这样的QObject的成员函数使用这些内省函数来完成它们的工作。


OpenCV是一个基于开源发行的跨平台计算机视觉库,它轻量级而且高效——由一系列 C 函数和少量 C++ 类构成,同时提供了Python、Ruby、MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法。

当前最新的版本是2.4.8,下载地址

一些入门教程:

OpenCV学习笔记:快速入门例程

OpenCV入门指南


更多图像处理、机器视觉资源请关注 博客:LinJM-机器视觉 微博:林建民-机器视觉

2007-12-03 10:16:00 colorant 阅读数 12199

  一两年前写的了,贴上来

作者:刘旭晖 colorant@163.com 转载请注明出处

http://blog.csdn.net/colorant/

1         前言
做为拍照手机的核心模块之一,camera sensor效果的调整,涉及到众多的参数,如果对基本的光学原理及sensor软/硬件对图像处理的原理能有深入的理解和把握的话,对我们的工作将会起到事半功倍的效果。否则,缺乏了理论的指导,只能是凭感觉和经验去碰,往往无法准确的把握问题的关键,不能掌握sensor调试的核心技术,无法根本的解决问题。
所以,这里笔者结合自己出于对摄影的爱好所学习的一些图像处理相关的原理,试图通过分析一些与Sensor图像处理相关的因素,和大家分享一下自己的一些理解,共同探讨,共同学习进步。
2         色彩感应及校正
2.1        原理
人眼对色彩的识别,是基于人眼对光线存在三种不同的感应单元,不同的感应单元对不同波段的光有不同的响应曲线的原理,通过大脑的合成得到色彩的感知。 一般来说,我们可以通俗的用RGB三基色的概念来理解颜色的分解和合成。
 
理论上,如果人眼和sensor对光谱的色光的响应,在光谱上的体现如下的话,基本上对三色光的响应,相互之间不会发生影响,没有所谓的交叉效应。
 
但是,实际情况并没有如此理想,下图表示了人眼的三色感应系统对光谱的响应情况。可见RGB的响应并不是完全独立的。
下图则表示了某Kodak相机光谱的响应。可见其与人眼的响应曲线有较大的区别。
2.2        对sensor的色彩感应的校正
既然我们已经看到sensor对光谱的响应,在RGB各分量上与人眼对光谱的响应通常是有偏差的,当然就需要对其进行校正。不光是在交叉效应上,同样对色彩各分量的响应强度也需要校正。通常的做法是通过一个色彩校正矩阵对颜色进行一次校正。

1

该色彩校正的运算通常是由sensor模块集成或后端的ISP完成,软件通过修改相关寄存器得到正确的校正结果。值得注意的一点是,由于RGB -> YUV的转换也是通过一个3*3的变换矩阵来实现的,所以有时候这两个矩阵在ISP处理的过程中会合并在一起,通过一次矩阵运算操作完成色彩的校正和颜色空间的转换。
3         颜色空间
3.1        分类
实际上颜色的描述是非常复杂的,比如RGB三基色加光系统就不能涵盖所有可能的颜色,出于各种色彩表达,以及色彩变换和软硬件应用的需求,存在各种各样的颜色模型及色彩空间的表达方式。这些颜色模型,根据不同的划分标准,可以按不同的原则划分为不同的类别。
匹配任意可见光所需的三原色光比例曲线
 
对于sensor来说,我们经常接触到的色彩空间的概念,主要是RGB , YUV这两种(实际上,这两种体系包含了许多种不同的颜色表达方式和模型,如sRGB, Adobe RGB, YUV422, YUV420 …), RGB如前所述就是按三基色加光系统的原理来描述颜色,而YUV则是按照 亮度,色差的原理来描述颜色。
3.1.1                RGB <-> YUV的转换
不比其它颜色空间的转换有一个标准的转换公式,因为YUV在很大程度上是与硬件相关的,所以RGB与YUV的转换公式通常会多个版本,略有不同。
 
常见的公式如下:
Y=0.30R+0.59G+0.11B
U=0.493(B
Y) = 0.15R0.29G+0.44B
V=0.877(R
Y) = 0.62R0.52G0.10B
 
但是这样获得的YUV值存在着负值以及取值范围上下限之差不为255等等问题,不利于计算机处理,所以根据不同的理解和需求,通常在软件处理中会用到各种不同的变形的公式,这里就不列举了。
体现在Sensor上,我们也会发现有些Sensor可以设置YUV的输出取值范围。原因就在于此。
从公式中,我们关键要理解的一点是,UV 信号实际上就是蓝色差信号和红色差信号,进而言之,实际上一定程度上间接的代表了蓝色和红色的强度,理解这一点对于我们理解各种颜色变换处理的过程会有很大的帮助。
 
2012-09-01 19:20:54 xiaoxia19920920 阅读数 1057

本人做了一个图片浏览器,用了一些图像处理的算法,这个是一部分,APK安装包地址:http://static.apk.hiapk.com/html/2012/08/797656.html,欢迎下载和反馈;

关于android系统图像特效处理之光照效果

public static Bitmap sunshine(SoftReference<Bitmap> bmp)  
    {  	
		
        final int width = bmp.get().getWidth();  
        final int height = bmp.get().getHeight();  
        Log.d("sunshine", "sunshine:width"+width+"height:"+height);
        Bitmap bitmap = (Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565));  
          
        int pixR = 0;  
        int pixG = 0;  
        int pixB = 0;  
          
        int pixColor = 0;  
          
        int newR = 0;  
        int newG = 0;  
        int newB = 0;  
          
        int centerX = width / 2;  
        int centerY = height / 2;  
        int radius = Math.min(centerX, centerY);  
          
        final float strength = 150F; // 光照强度 100~150  
        int[] pixels = new int[width * height];  
        bmp.get().getPixels(pixels, 0, width, 0, 0, width, height);  
        int pos = 0;  
        
//        bmp.recycle();
//        bmp = null;
        for (int i = 1, length = height - 1; i < length; i++)  
        {  
            for (int k = 1, len = width - 1; k < len; k++)  
            {  
            	
                pos = i * width + k;  
                pixColor = pixels[pos];  
                  
                pixR = Color.red(pixColor);  
                pixG = Color.green(pixColor);  
                pixB = Color.blue(pixColor);  
                  
                newR = pixR;  
                newG = pixG;  
                newB = pixB;  
                  
                // 计算当前点到光照中心的距离,平面座标系中求两点之间的距离  v 
                int distance = (int) (Math.pow((centerY - i), 2) + Math.pow(centerX - k, 2));  
                if (distance < radius * radius)  
                {  
                    // 按照距离大小计算增加的光照值  
                    int result = (int) (strength * (1.0 - Math.sqrt(distance) / radius));  
                    newR = pixR + result;  
                    newG = pixG + result;  
                    newB = pixB + result;  
                }  
                  
                newR = Math.min(255, Math.max(0, newR));  
                newG = Math.min(255, Math.max(0, newG));  
                newB = Math.min(255, Math.max(0, newB));  
                  
                pixels[pos] = Color.argb(255, newR, newG, newB);  
            }  
        }  
        
        bitmap.setPixels(pixels, 0, width, 0, 0, width, height);  
        return bitmap;  
    }


 

2019-10-24 22:06:44 weixin_37119423 阅读数 189

       在泵站安装了海康威视的摄像头,晚上发现球机一直在闪烁,大约闪烁时间为3秒闪一次,百思不得其解,仔细审视摄像头的配置,未发现有可疑的选择,后来在网上查阅资料发现应该是补光灯闪烁的问题,于是在  系统——系统维护——系统服务  里面关闭【启用补光灯】功能才得以解决,关闭之后存在延迟,需要等待一段时间,我们出去吃饭回来就发现已恢复正常。

2014-04-14 19:40:12 iteye_11349 阅读数 57
[size=large]之前经常使用光影魔术手3的补光操作,那么,其补光的原理是什么呢?

老规矩,先上[color=red]结论[/color]:
[color=blue]    光影魔术手的补光相当于调整曲线操作,曲线映射关系如下:[/color][/size]

[img]http://dl2.iteye.com/upload/attachment/0096/1066/824b2e4c-e242-349f-af94-3d12728ddbc4.png[/img]

[size=large][color=blue]连续补光两次[/color],曲线如下:[/size]
[img]http://dl2.iteye.com/upload/attachment/0096/1075/2fd7f3c8-82ec-3563-8b95-26aefe7f03cc.png[/img]


[size=large]有时,我会[color=blue]先补光两次,再调整一下gamma值[/color],其曲线如下:[/size]
[img]http://dl2.iteye.com/upload/attachment/0096/1071/20ff6384-8cef-3cc9-a84d-ed9f4fd6589a.png[/img]


[color=blue][size=large]附上补光的映射表的matlab函数封装:[/size][/color]

function y=BuGuangTable(x)
% 光影魔术手的补光映射表
% Input:
% x: 整数,x \in [0, 255]
% Output:
% y:整数,y \in [0, 255]

y_uint8=[0,2,3,5,6,8,10,11,13,14,16,18,19,21,22,23,25,27,28,30,31,32,33,35,36,38,39,41,42,44,45,46,47,49,51,52,53,55,56,57,59,60,62,63,64,65,67,68,70,71,71,73,75,76,77,78,79,81,82,83,84,86,87,88,89,91,92,93,94,95,97,98,99,100,101,102,104,105,106,107,109,109,110,112,113,114,115,116,117,118,120,120,122,123,124,125,126,127,127,129,130,131,132,133,134,135,136,137,138,139,140,141,142,142,144,145,145,146,147,148,149,150,151,152,153,154,155,156,156,157,158,159,160,161,162,163,164,164,166,166,167,168,169,170,171,171,173,173,174,175,176,176,178,178,179,180,181,181,182,182,183,183,184,185,185,186,186,187,188,188,189,190,190,191,192,192,193,193,194,195,195,196,197,197,198,199,199,200,201,201,202,203,203,204,205,205,206,207,207,208,209,210,210,211,212,213,213,214,215,215,216,217,218,218,219,220,221,222,222,223,224,225,226,227,227,228,229,230,231,231,232,233,234,235,236,237,238,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,255];
y=y_uint8(x+1);
end



[color=blue][size=large]% 测试光影魔术手补光的响应曲线[/size][/color]

%%生成测试图像

imr1=0:255;
imr2=[1:255 0];
imr3=255:-1:0;

im=[imr1; imr1; imr2;imr2; imr3;imr3];
im=uint8(im);
imwrite(im,'gray.bmp'); %为了保证像素值不因为jpg的压缩而改变,这里使用bmp格式

%% 验证光影魔术手的补光操作只是一个灰度映射操作;
%需要先用 光影魔术手对'gray.bmp'补光后存为'grayDisposed.bmp'

imDisposed=imread('grayDisposed.bmp');
imDG=imDisposed(:,:,1);

all(imDG(1,:)==imDG(2,:))
all(imDG(3,:)==imDG(4,:))
all(imDG(5,:)==imDG(6,:))

all(imDG(2,:)==[imDG(3,end) imDG(3,1:end-1)])

r2Equal_r5=all(imDG(2,:)==imDG(5,end:-1:1) )


%% 绘制光影魔术手补光的响应曲线
modeName='光影魔术手补光';

x=linspace(0,1,256);
y_uint8=imDG(1,:);
y=double(y_uint8)/255;


figure1 = figure;
axes1 = axes('Parent',figure1,'YTick',0:.1:1,'XTick',0:.1:1,...
'PlotBoxAspectRatio',[1 1 1],...
'DataAspectRatio',[1 1 1]);
% xlim(axes1,[0 1]);
% ylim(axes1,[0 1]);
grid on
box(axes1,'on');
hold(axes1,'all');

plot(x,y,'Parent',axes1,'LineWidth',3,'Color',[1 0 0], 'DisplayName',modeName);
plot(x,x,'Parent',axes1,'LineWidth',2,'LineStyle','--', 'DisplayName','正常模式');

xlabel('补光前的灰度值','FontSize',16);
ylabel('补光后的灰度值','FontSize',16);
title([modeName ' 响应曲线'],'FontSize',16);
legend1 = legend(axes1,'show');
set(legend1,'Location','SouthEast');
% clear all

%%
modeName='光影魔术手补光2次';

x=linspace(0,1,256);

y=BuGuangTable(BuGuangTable(0:255))/255;

figure1 = figure;
axes1 = axes('Parent',figure1,'YTick',0:.1:1,'XTick',0:.1:1,...
'PlotBoxAspectRatio',[1 1 1],...
'DataAspectRatio',[1 1 1]);
% xlim(axes1,[0 1]);
% ylim(axes1,[0 1]);
grid on
box(axes1,'on');
hold(axes1,'all');

plot(x,y,'Parent',axes1,'LineWidth',3,'Color',[1 0 0], 'DisplayName',modeName);
plot(x,x,'Parent',axes1,'LineWidth',2,'LineStyle','--', 'DisplayName','正常模式');

xlabel('补光前的灰度值','FontSize',16);
ylabel('补光后的灰度值','FontSize',16);
title([modeName ' 响应曲线'],'FontSize',16);
legend1 = legend(axes1,'show');
set(legend1,'Location','SouthEast');

%%
modeName='补光2次, 参数为1.2的gamma校正一次';

x=linspace(0,1,256);

y=BuGuangTable(BuGuangTable(0:255))/255;
% y=BuGuangTable(0:255)/255;
y=y.^1.2;

figure1 = figure;
axes1 = axes('Parent',figure1,'YTick',0:.1:1,'XTick',0:.1:1,...
'PlotBoxAspectRatio',[1 1 1],...
'DataAspectRatio',[1 1 1]);
% xlim(axes1,[0 1]);
% ylim(axes1,[0 1]);
grid on
box(axes1,'on');
hold(axes1,'all');

plot(x,y,'Parent',axes1,'LineWidth',3,'Color',[1 0 0], 'DisplayName',modeName);
plot(x,x,'Parent',axes1,'LineWidth',2,'LineStyle','--', 'DisplayName','正常模式');

xlabel('补光前的灰度值','FontSize',16);
ylabel('补光后的灰度值','FontSize',16);
title([ modeName ' 响应曲线'],'FontSize',16);
legend1 = legend(axes1,'show');
set(legend1,'Location','SouthEast');



[size=large]完整代码、图片见附件~[/size]
没有更多推荐了,返回首页