ISP模块之色彩增强算法--HSV空间Saturation通道调整 .
色彩增强不同于彩色图像增强,图像增强的一般处理方式为直方图均衡化等,目的是为了增强图像局部以及整体对比度。而色彩增强的目的是为了使的原有的不饱和的色彩信息变得饱和、丰富起来。对应于Photoshop里面的“色相/饱和度”调节选项里面对饱和度的操作。色彩增强的过程,并不改变原有彩色图像的颜色以及亮度信息。
在我的色彩增强算法模块里面,始终只针对色彩饱和度(Saturation)信息做研究,调整。这样的话,那就不得不介绍HSV颜色空间了,H代表Hue(色彩),S代表Saturation(饱和度),V代表Value,也可用B表示(Brightness,明度),HSV空间也可称作HSB空间。
HSV空间在wikipedia上的介绍,https://en.wikipedia.org/wiki/HSL_and_HSV
下面根据自己的理解介绍一下HSV空间,以及其各通道在Matlab和OpenCV中的不同。
HSV的圆柱模型
HSV的圆锥模型
从上图可以看出,在HSV空间中,Hue通道的取值从0-360°变化时,颜色从红->黄->绿->青->蓝逐步变化。Saturation从0->1变化时,色彩逐渐加深变成纯色(pure)。Value值从0->1变化时,图像整体亮度增加,V值为0时,图像为全黑,V值为1时,图像为全白。
Matlab RGB色彩空间向HSV转换,采用函数rgb2hsv,转换后的hsv各通道的元素取值范围为[0,1];OpenCV中彩色图像向HSV空间中转换,cvtColor(src,srcHsv,CV_BGR2HSV),转换后H的取值范围为[0,180],S,V的取值范围为[0,255].
下面介绍自己的算法处理思路,后面会给出完整的Matlab代码:
步骤一、给出一张原图src,用PS进行饱和度(Saturation)+40处理后另存为src_40;
步骤二、将以上两张图像分别转换到hsv空间,提取出饱和度信息,分别为S,S_40;
步骤三、统计饱和度增加40后,原色彩饱和度与饱和度增量之间的对应关系,即S -- (S_40-S);
步骤四、对关系S -- (S_40-S)进行二次多项式曲线拟合,得到二次曲线f(x) = p1*x^2 + p2*x + p3;
为什么是二次?1.对应关系呈现出抛物线形状;2.更高次曲线并没有明显改善拟合性能,且计算消耗会变高。
步骤五、任意给定输出图像input,根据其色彩饱和度信息,即可进行色彩增强40处理,新的饱和度信息可以表示为S'(x) = S(x) + f(x),得到增强后的色彩信息后返回RGB图像输出;
步骤六、分别对原图+20,+40,+60后进行饱和度信息统计,并得到相应拟合参数,设置为色彩增强的低、中、高三挡,在实际处理过程中,根据输入图像input自身色彩饱和度信息(均值)自适应选取相应参数进行色彩增强;
步骤七、按需对某一单独颜色通道进行色彩增强处理,例如绿色范围为105°-135°,在对该范围进行增强的同时,还需对75°-105°,135°-165°进行一半强度的增强,这样才会保证色彩的连续性,不会出现色斑;
步骤八、按需对色彩(Hue)进行转换;
代码部分:第一部分用作估计拟合参数,在Curve fitting tool里面对X,Y进行拟合,得到曲线参数。
- % Color Enhancement
- clc,clear,close all
- src1 = imread('src.bmp');
- src2 = imread('src_40.bmp');
- src1_hsv = rgb2hsv(src1);
- src2_hsv = rgb2hsv(src2);
- h1 = src1_hsv(:,:,1);
- s1 = src1_hsv(:,:,2);
- v1 = src1_hsv(:,:,3);
- h2 = src2_hsv(:,:,1);
- s2 = src2_hsv(:,:,2);
- v2 = src2_hsv(:,:,3);
- %
- meanS1 = mean(s1(:));
- varS1 = std2(s1);
- %
- meanS2 = mean(s2(:));
- varS2 = std2(s2);
- %
- deltaS = s2 - s1;
- deltaV = v2 - v1;
- %% test1 : 观测“原饱和度-饱和度调整增量”的关系 saturation and delta saturation
- figure;
- oriS = zeros(101,2);
- s3 = s1;
- j = 1;
- for i = 0: 0.01 : 1
- oriS(j,1) = i + 0.01;
- oriS(j,2) = mean(deltaS(find(s1 > i & s1< i + 0.01)));
- j = j + 1;
- end
- X = oriS(:,1);
- Y = oriS(:,2);
- XX = oriS(:,1) * 255;
- YY = oriS(:,2) * 255;
- plot(XX,YY)
% Color Enhancement
clc,clear,close all
src1 = imread('src.bmp');
src2 = imread('src_40.bmp'); src1_hsv = rgb2hsv(src1);
src2_hsv = rgb2hsv(src2); h1 = src1_hsv(:,:,1);
s1 = src1_hsv(:,:,2);
v1 = src1_hsv(:,:,3); h2 = src2_hsv(:,:,1);
s2 = src2_hsv(:,:,2);
v2 = src2_hsv(:,:,3);
%
meanS1 = mean(s1(:));
varS1 = std2(s1);
%
meanS2 = mean(s2(:));
varS2 = std2(s2);
%
deltaS = s2 - s1;
deltaV = v2 - v1; %% test1 : 观测“原饱和度-饱和度调整增量”的关系 saturation and delta saturation
figure;
oriS = zeros(101,2);
s3 = s1;
j = 1;
for i = 0: 0.01 : 1
oriS(j,1) = i + 0.01;
oriS(j,2) = mean(deltaS(find(s1 > i & s1< i + 0.01)));
j = j + 1;
end
X = oriS(:,1);
Y = oriS(:,2);
XX = oriS(:,1) * 255;
YY = oriS(:,2) * 255;
plot(XX,YY)
第二部分,对输入图像进行高、中、低三级自适应增强处理
- %% Color Enhancement Module -- Authored by HuangDao,08/17/2015
- % functions: input a image of type BMP or PNG, the program will decide to
- % do the Color Enhancement choice for you.There are four types of Enhanced
- % intensity - 20,40,60,80.The larger number stands for stronger
- % enhancement.
- % And we can also choose the simple color channel(eg.R,G,B) to do the
- % enhancement.There are also four different types of enhanced intensity.
- %
- % parameters table
- % ------------------------------------------------------------------------
- % | Enhanced | MATLAB params | OpenCV params |
- % | intensity |p1 p2 p3 | p1 p2 p3 |
- % | 20 |-0.1661 0.2639 -0.003626 |-0.0006512 0.2639 -0.9246|
- % | 40 |-0.4025 0.6238 -0.0005937 |0.001578 0.6238 -0.1514|
- % | 60 |1.332 1.473 -0.01155 |-0.005222 1.473 -2.946 |
- % | 80 |-4.813 3.459 -0.004568 |-0.01887 3.459 -1.165 |
- % ------------------------------------------------------------------------
- clc; clear ;close all
- % 载入文件夹
- pathName = '.\';
- fileType = '*.bmp';
- files = dir([pathName fileType]);
- len = length(files);
- for pic = 5%1:1:len
- srcName = files(pic).name;
- srcImg = imread(srcName);
- srcHSV = rgb2hsv(srcImg);
- srcH = srcHSV(:,:,1);
- srcS = srcHSV(:,:,2);
- srcV = srcHSV(:,:,3);
- meanS = mean(srcS(:));
- varS = std2(srcS);
- %图像整体进行色彩增强处理
- if (meanS >= 0.5)
- p1 = 0;p2 = 0;p3 = 0;
- else if (meanS >= 0.35 && meanS < 0.5)
- p1 = -0.1661;p2 = 0.2639;p3 = -0.003626;
- else if (meanS >=0.2 && meanS <0.35)
- p1 = -0.4025;p2 = 0.6238;p3 = -0.0005937;
- else
- p1 = 1.332;p2 = 1.473;p3 = -0.01155;
- end
- end
- end
- dstS = srcS + p1*srcS.*srcS + p2*srcS + p3 ;
- dstHSV = srcHSV;
- dstHSV(:,:,2) = dstS;
- dstImg = hsv2rgb(dstHSV);
- figure;imshow(srcImg);
- figure;imshow(dstImg);
- %指定R,G,B通道进行色彩增强处理,红色范围([225-255]),绿色范围(75-[105-135]-165),蓝色范围([-15-15])
- p11 = -0.4025;p21 = 0.6238;p31 = -0.0005937;%周边杂色调整系数,40
- p12 = 1.332; p22 = 1.473; p32 = -0.01155; %纯色区域调整系数,60
- compHue = srcH;
- GcompS = dstS;
- RcompS = dstS;
- BcompS = dstS;
- channel = 'B';
- switch channel
- case 'G'
- I1 = find(compHue > 0.2083 & compHue <0.2917);
- GcompS(I1) = dstS(I1) + dstS(I1).*dstS(I1)*p11 + dstS(I1)*p21 + p31;
- I2 = find(compHue >= 0.2917 & compHue <= 0.3750);
- GcompS(I2) = dstS(I2) + dstS(I2).*dstS(I2)*p12 + dstS(I2)*p22 + p32;
- I3 = find(compHue > 0.3750 & compHue <0.4583);
- GcompS(I3) = dstS(I3) + dstS(I3).*dstS(I3)*p11 + dstS(I3)*p21 + p31;
- compHSV = dstHSV;
- compHSV(:,:,2) = GcompS;
- dstImgG = hsv2rgb(compHSV);
- figure;imshow(dstImgG);
- case 'R'
- I1 = find(compHue > 0.875 & compHue <0.9583);
- RcompS(I1) = dstS(I1) + dstS(I1).*dstS(I1)*p11 + dstS(I1)*p21 + p31;
- I2 = find(compHue >= 0.9583 | compHue <= 0.0417);
- RcompS(I2) = dstS(I2) + dstS(I2).*dstS(I2)*p12 + dstS(I2)*p22 + p32;
- I3 = find(compHue > 0.0417 & compHue <0.125);
- RcompS(I3) = dstS(I3) + dstS(I3).*dstS(I3)*p11 + dstS(I3)*p21 + p31;
- compHSV = dstHSV;
- compHSV(:,:,2) = RcompS;
- dstImgR = hsv2rgb(compHSV);
- figure;imshow(dstImgR);
- case 'B'
- I1 = find(compHue > 0.5417 & compHue <0.625);
- BcompS(I1) = dstS(I1) + dstS(I1).*dstS(I1)*p11 + dstS(I1)*p21 + p31;
- I2 = find(compHue >= 0.625 & compHue <= 0.7083);
- BcompS(I2) = dstS(I2) + dstS(I2).*dstS(I2)*p12 + dstS(I2)*p22 + p32;
- I3 = find(compHue > 0.7083 & compHue <0.7917);
- BcompS(I3) = dstS(I3) + dstS(I3).*dstS(I3)*p11 + dstS(I3)*p21 + p31;
- compHSV = dstHSV;
- compHSV(:,:,2) = BcompS;
- dstImgB = hsv2rgb(compHSV);
- figure;imshow(dstImgB);
- end
- %进行R,G,B通道之间的互换
- convH = zeros(size(srcH,1),size(srcH,2)); %convert
- deltaHue = 240;
- switch deltaHue
- case 120
- disp('R -> G')
- convH = srcH + 1/3;
- convH(find(convH >= 1)) = convH(find(convH >= 1)) - 1;
- case 240
- disp('R -> B')
- convH = srcH + 2/3;
- convH(find(convH >= 1)) = convH(find(convH >= 1)) - 1;
- end
- convHSV = dstHSV;
- convHSV(:,:,1) = convH;
- convImg = hsv2rgb(convHSV);
- figure;imshow(convImg)
- pause();
- end
%% Color Enhancement Module -- Authored by HuangDao,08/17/2015
% functions: input a image of type BMP or PNG, the program will decide to
% do the Color Enhancement choice for you.There are four types of Enhanced
% intensity - 20,40,60,80.The larger number stands for stronger
% enhancement.
% And we can also choose the simple color channel(eg.R,G,B) to do the
% enhancement.There are also four different types of enhanced intensity.
%
% parameters table
% ------------------------------------------------------------------------
% | Enhanced | MATLAB params | OpenCV params |
% | intensity |p1 p2 p3 | p1 p2 p3 |
% | 20 |-0.1661 0.2639 -0.003626 |-0.0006512 0.2639 -0.9246|
% | 40 |-0.4025 0.6238 -0.0005937 |0.001578 0.6238 -0.1514|
% | 60 |1.332 1.473 -0.01155 |-0.005222 1.473 -2.946 |
% | 80 |-4.813 3.459 -0.004568 |-0.01887 3.459 -1.165 |
% ------------------------------------------------------------------------ clc; clear ;close all
% 载入文件夹
pathName = '.\';
fileType = '*.bmp';
files = dir([pathName fileType]);
len = length(files); for pic = 5%1:1:len
srcName = files(pic).name;
srcImg = imread(srcName);
srcHSV = rgb2hsv(srcImg);
srcH = srcHSV(:,:,1);
srcS = srcHSV(:,:,2);
srcV = srcHSV(:,:,3);
meanS = mean(srcS(:));
varS = std2(srcS);
%图像整体进行色彩增强处理
if (meanS >= 0.5)
p1 = 0;p2 = 0;p3 = 0;
else if (meanS >= 0.35 && meanS < 0.5)
p1 = -0.1661;p2 = 0.2639;p3 = -0.003626;
else if (meanS >=0.2 && meanS <0.35)
p1 = -0.4025;p2 = 0.6238;p3 = -0.0005937;
else
p1 = 1.332;p2 = 1.473;p3 = -0.01155;
end
end
end
dstS = srcS + p1*srcS.*srcS + p2*srcS + p3 ;
dstHSV = srcHSV;
dstHSV(:,:,2) = dstS;
dstImg = hsv2rgb(dstHSV);
figure;imshow(srcImg);
figure;imshow(dstImg);
%指定R,G,B通道进行色彩增强处理,红色范围([225-255]),绿色范围(75-[105-135]-165),蓝色范围([-15-15])
p11 = -0.4025;p21 = 0.6238;p31 = -0.0005937;%周边杂色调整系数,40
p12 = 1.332; p22 = 1.473; p32 = -0.01155; %纯色区域调整系数,60
compHue = srcH;
GcompS = dstS;
RcompS = dstS;
BcompS = dstS;
channel = 'B';
switch channel
case 'G'
I1 = find(compHue > 0.2083 & compHue <0.2917);
GcompS(I1) = dstS(I1) + dstS(I1).*dstS(I1)*p11 + dstS(I1)*p21 + p31;
I2 = find(compHue >= 0.2917 & compHue <= 0.3750);
GcompS(I2) = dstS(I2) + dstS(I2).*dstS(I2)*p12 + dstS(I2)*p22 + p32;
I3 = find(compHue > 0.3750 & compHue <0.4583);
GcompS(I3) = dstS(I3) + dstS(I3).*dstS(I3)*p11 + dstS(I3)*p21 + p31;
compHSV = dstHSV;
compHSV(:,:,2) = GcompS;
dstImgG = hsv2rgb(compHSV);
figure;imshow(dstImgG);
case 'R'
I1 = find(compHue > 0.875 & compHue <0.9583);
RcompS(I1) = dstS(I1) + dstS(I1).*dstS(I1)*p11 + dstS(I1)*p21 + p31;
I2 = find(compHue >= 0.9583 | compHue <= 0.0417);
RcompS(I2) = dstS(I2) + dstS(I2).*dstS(I2)*p12 + dstS(I2)*p22 + p32;
I3 = find(compHue > 0.0417 & compHue <0.125);
RcompS(I3) = dstS(I3) + dstS(I3).*dstS(I3)*p11 + dstS(I3)*p21 + p31;
compHSV = dstHSV;
compHSV(:,:,2) = RcompS;
dstImgR = hsv2rgb(compHSV);
figure;imshow(dstImgR);
case 'B'
I1 = find(compHue > 0.5417 & compHue <0.625);
BcompS(I1) = dstS(I1) + dstS(I1).*dstS(I1)*p11 + dstS(I1)*p21 + p31;
I2 = find(compHue >= 0.625 & compHue <= 0.7083);
BcompS(I2) = dstS(I2) + dstS(I2).*dstS(I2)*p12 + dstS(I2)*p22 + p32;
I3 = find(compHue > 0.7083 & compHue <0.7917);
BcompS(I3) = dstS(I3) + dstS(I3).*dstS(I3)*p11 + dstS(I3)*p21 + p31;
compHSV = dstHSV;
compHSV(:,:,2) = BcompS;
dstImgB = hsv2rgb(compHSV);
figure;imshow(dstImgB);
end
%进行R,G,B通道之间的互换
convH = zeros(size(srcH,1),size(srcH,2)); %convert
deltaHue = 240;
switch deltaHue
case 120
disp('R -> G')
convH = srcH + 1/3;
convH(find(convH >= 1)) = convH(find(convH >= 1)) - 1;
case 240
disp('R -> B')
convH = srcH + 2/3;
convH(find(convH >= 1)) = convH(find(convH >= 1)) - 1;
end
convHSV = dstHSV;
convHSV(:,:,1) = convH;
convImg = hsv2rgb(convHSV);
figure;imshow(convImg)
pause();
end
添加OpenCV代码段:
- Mat srcHSV,sat,satAdj,dstMerge,dst; //sat - saturation饱和度分量
- Mat imageAwb = imread("m_ImageAwb.bmp");
- vector<Mat> channels,channels1;
- double p1,p2,p3;
- cvtColor(imageAwb,srcHSV,CV_BGR2HSV);
- split(srcHSV,channels);
- split(srcHSV,channels1);
- sat = channels.at(1);
- Scalar m = mean(sat);
- if (m(0) <= 51.5)
- {p1 = -0.002714 , p2 = 0.9498, p3 = -0.5073; AfxMessageBox("High Color Enhancement!"); }//高
- else if (m(0) > 38.5 && m(0) <= 89.5)
- {p1 = -0.001578 , p2 = 0.6238, p3 = -0.1514;AfxMessageBox("Middle Color Enhancement!"); }//中
- else if (m(0) > 89.5 && m(0) <=127.5)
- {p1 = -0.0006512, p2 = 0.2639, p3 = -0.9246;AfxMessageBox("Low Color Enhancement!");}//低
- else
- {p1 = 0,p2 = 0,p3 =0;AfxMessageBox("No Color Enhancement!");}
- satAdj = sat;
- for (int i = 0 ; i < sat.rows;i ++)
- {
- for (int j = 0;j < sat.cols;j ++)
- {
- uchar val = sat.at<uchar>(i,j);
- satAdj.at<uchar>(i,j) = (val + p1 * val * val + p2 * val + p3) ;
- }
- }
- channels1.at(1) = satAdj;
- merge(channels1,dstMerge);
- cvtColor(dstMerge,dst,CV_HSV2BGR);
- imwrite("m_ImageCE.bmp",dst);
Mat srcHSV,sat,satAdj,dstMerge,dst; //sat - saturation饱和度分量
Mat imageAwb = imread("m_ImageAwb.bmp");
vector<Mat> channels,channels1;
double p1,p2,p3; cvtColor(imageAwb,srcHSV,CV_BGR2HSV);
split(srcHSV,channels);
split(srcHSV,channels1);
sat = channels.at(1);
Scalar m = mean(sat); if (m(0) <= 51.5)
{p1 = -0.002714 , p2 = 0.9498, p3 = -0.5073; AfxMessageBox("High Color Enhancement!"); }//高
else if (m(0) > 38.5 && m(0) <= 89.5)
{p1 = -0.001578 , p2 = 0.6238, p3 = -0.1514;AfxMessageBox("Middle Color Enhancement!"); }//中
else if (m(0) > 89.5 && m(0) <=127.5)
{p1 = -0.0006512, p2 = 0.2639, p3 = -0.9246;AfxMessageBox("Low Color Enhancement!");}//低
else
{p1 = 0,p2 = 0,p3 =0;AfxMessageBox("No Color Enhancement!");} satAdj = sat;
for (int i = 0 ; i < sat.rows;i ++)
{
for (int j = 0;j < sat.cols;j ++)
{
uchar val = sat.at<uchar>(i,j);
satAdj.at<uchar>(i,j) = (val + p1 * val * val + p2 * val + p3) ;
}
} channels1.at(1) = satAdj;
merge(channels1,dstMerge);
cvtColor(dstMerge,dst,CV_HSV2BGR);
imwrite("m_ImageCE.bmp",dst);
最后给出算法效果图:
Group1.原图->增强后
Group2.原图->R通道增强->颜色通道改变R2B
Group3.原图->增强后->颜色通道改变R2B
完!下篇讲Local Tone Mapping。
ISP模块之色彩增强算法--HSV空间Saturation通道调整 .的更多相关文章
- ISP模块之RAW DATA去噪(二)--BM3D算法
在正式开始本篇文章之前,让我们一起回顾一下CFA图像去噪的一些基本思路与方法.接着我会详细地和大家分享自己学习理解的BM3D算法,操作过程,它的优缺点,最后会给出算法效果图供参考. 在ISP模块里,研 ...
- ISP模块之彩色图像增强--ACE算法 .
ACE(Automatic Color Enhancement),自动色彩增强算法,是一种对于彩色图像增强十分行之有效的方法.它的改进算法以及快速实现在文章Automatic Color Enhanc ...
- ISP基本框架及算法介绍
什么是ISP,他的工作原理是怎样的? ISP是Image Signal Processor的缩写,全称是影像处理器.在相机成像的整个环节中,它负责接收感光元件(Sensor)的原始信号数据,可以理解为 ...
- 运动目标检测中基于HSV空间的阴影去除算法
在运动目标检测中,常常会出现由于光线被遮挡,或场景其他物体的遮挡,在目标附近或场景里出现阴影,阴影的出现对后期目标的正确分割与处理带了很大的不便.如今,国内外已有不少文献来研究这个问题,并且提出了各种 ...
- ISP模块之RAW DATA去噪(一)
ISP(Image Signal Processor),图像信号处理器,主要用来对前端图像传感器输出信号处理的单元,主要用于手机,监控摄像头等设备上. RAW DATA,可以理解为:RAW图像就是CM ...
- [算法]检测空间三角形相交算法(Devillers & Guigue算法)
#pragma once //GYDevillersTriangle.h /* 快速检测空间三角形相交算法的代码实现(Devillers & Guigue算法) 博客原地址:http://bl ...
- 关于tarjan算法的空间优化
最近随着对tarjan算法理解的加深,我发现用另外一种途径实现tarjan的方法,且可以省去DFN数组,大大节省了空间.经过大量测试,已经无误.以下将分阶段阐述进行优化的过程. 第一阶段 下面来说一下 ...
- hsv空间
hsv在不同的软件中,有不同的阈值, 在描述阈值之前,看一下它的定义,按照标准的定义,hsv应该是从0°到360°的一个环,加上一个表示亮度的轴,重点就是那个环. 这个环如图一,0°一般为红色120° ...
- pcl曲面重建模块-poisson重建算法示例
poisson曲面重建算法 pcl-1.8测试通过 #include <iostream> #include <pcl/common/common.h> #include &l ...
随机推荐
- bzoj1009 [HNOI2008] GT考试 矩阵乘法+dp+kmp
1009: [HNOI2008]GT考试 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 4542 Solved: 2815[Submit][Statu ...
- vs2008升级正式版
1.VS2008简体中文正式版序列号 1.Visual Studio 2008 Professional Edition: XMQ2Y-4T3V6-XJ48Y-D3K2V-6C4WT 2.Visual ...
- 狂K 线段树
想写好树剖~~线段树very important HDU 1166 敌兵布阵 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536 ...
- 自定义View Measure过程(2)
目录 目录 1. 作用 测量View的宽/高 在某些情况下,需要多次测量(measure)才能确定View最终的宽/高: 在这种情况下measure过程后得到的宽/高可能是不准确的: 建议在layou ...
- Java学习之Iterator(迭代器)
迭代器(Iterator) 迭代器是一种设计模式,它是一个对象,它可以遍历并选择序列中的对象,而开发人员不需要了解该序列的底层结构.迭代器通常被称为“轻量级”对象,因为创建它的代价小. Java中的I ...
- Linux的日志错误级别
讯息等级 系统将讯息分为七个主要的等级,依序是由不重要排列到重要讯息等级: info:仅是一些基本的讯息说明而已: notice:比 info 还需要被注意到的一些信息内容: warning 或 wa ...
- Express定制参数解析错误响应值
Nodejs的Express框架本身所提供的东西并没有其它框架那么多.其中的一个问题就是对于请求数据的解析. express中的请求对象并没有未经过解析的请求体,几乎所有的请求体都要经过类似于body ...
- MSSQL—列记录合并成一行
在项目开发中,有时会碰到将列记录合并为一行的情况,例如根据地区将人员姓名合并,或根据拼音首字母合并城市等,下面就以根据地区将人员姓名合并为例,详细讲一下合并的方法. 首先,先建一个表,并添加一些数据, ...
- (12)oracle事务
事物 http://www.cnblogs.com/linjiqin/archive/2012/02/06/2340637.htm 在当前的事务中设置保存点 savepoint 名字; 保存点回滚 ...
- (12)C#枚举,结构
枚举 枚举类型是类似自定义的一个类,类里放着你自己定义的常量,关键字enum. enum Season{spring,summer,fall,winter} 想用这里的常量的话,首先把变量定义成 Se ...