请教自动色阶&色阶调整的算法和思路

whatkindu 2002-12-23 11:38:48
今天小弟在使用PS的时候使用了自动色阶和色阶调整,很是羡慕,小弟也想亲自编程实现一下,其实色阶不是太难,不过PS里面的可选项属实很多,所以请高手不吝赐教,
针对PS自动色阶和色阶调整,给出个算法或者思路,代码也可以.注意一般的色阶算法(傻瓜型的)就不用提供了.一经解决马上结帖,给大家多多UP.UP者也有分.
...全文
1133 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
whatkindu 2002-12-28
  • 打赏
  • 举报
回复
谢谢,hdaq(一生何求)
祝您新年快乐.
hdaq 2002-12-26
  • 打赏
  • 举报
回复
void __fastcall TForm1::Button3Click(TObject *Sender)
{
//在Image1中载入原始图象,本程序将以24位位图为例
//RGB图象拉伸
int ImgWidth,ImgHeight;
Byte *ScanLine1,*ScanLine2;
int BytesPerLine;

Byte min_RGBInput,max_RGBInput; //输入色阶
Byte min_RGBOutput,max_RGBOutput; //输出色阶

min_RGBInput = TrackBar1->Position; // 0 ~ 255
max_RGBInput = TrackBar2->Position; // 0 ~ 255
min_RGBOutput = TrackBar3->Position; // 0 ~ 255
max_RGBOutput = TrackBar4->Position; // 0 ~ 255

Byte *lpRGB;
lpRGB = (Byte*) calloc( 256, sizeof(Byte));

for(int i =0; i<= min_RGBInput; i++)
{
//小于最小输入色阶的均置为 min_RGBOutput最小输出色阶
lpRGB[i] = min_RGBOutput;
}
for(int i = min_RGBInput + 1; i < max_RGBInput ;i++)
{
//介于最大最小输入色阶 的色阶 按线性拉伸为 输出色阶
lpRGB[i] = min_RGBOutput + (Byte)floor(
(double)(i - min_RGBInput) /
(double)( max_RGBInput - min_RGBInput )*
(double)( max_RGBOutput - min_RGBOutput ) + 0.5);
}
for(int i = max_RGBInput;i<256;i++)
{
//大于最大输入色阶的均置为 max_RGBOutput最大输出色阶
lpRGB[i] = max_RGBOutput;
}

ImgWidth = Image1->Picture->Bitmap->Width;
ImgHeight = Image1->Picture->Bitmap->Height;
Image1->Picture->Bitmap->PixelFormat = pf24bit;
BytesPerLine = ImgWidth * 3;

Graphics::TBitmap *newbmp = new Graphics::TBitmap();
newbmp->Width = ImgWidth;
newbmp->Height = ImgHeight;
newbmp->PixelFormat = pf24bit;

for(int i=0;i<ImgHeight;i++)
{
ScanLine1 = static_cast<Byte*>(Image1->Picture->Bitmap->ScanLine[i]);
ScanLine2 = static_cast<Byte*>(newbmp->ScanLine[i]);
for(int j = 0;j < BytesPerLine; j++)
{
ScanLine2[j] = lpRGB[ScanLine1[j]];
}
}
free(lpRGB);
Image2->Picture->Bitmap->Assign(newbmp);
delete newbmp;

/*
至于中间色调,据我分析,实际上是将输入色阶按2个区域进行线性拉伸,
只不过PS将此系数化了。默认情况下为1.0,也就是输入色阶的中间值对应
输出色阶的中间值,这时PS的处理方法与我上面的算法结果一模一样,不信你可以试试。
我也不知道“中间系数”这个东西具体如何对应输入像素值,这里我就以
具体像素来说明一下:
如你的输入色阶为 20 ~ 200 ,中间色调系数为1.0(在此处此值对应像素为110,即20 ~ 200的中间值),
输出色阶为 40 ~ 240,这时就是将图象由20 ~200按线性地拉伸到 40 ~ 240。
如果中间色调系数不为1.0,则是将输入色阶按系数划分为两个区域(即20~某值(此值根据中间色调系数计算而来),某值~200),将输出色阶划分为
相等的两个区域(即40 ~ 140和 140 ~ 240),然后对应的将两个输入区域拉伸为两个色阶输出区域.
*/
}
//---------------------------------------------------------------------------
whatkindu 2002-12-25
  • 打赏
  • 举报
回复
谢谢hdaq,不过怎么"拉伸呢",还有"中间调"灰度系数是做什么的?
能不能具体解释一下,和给出算法来,谢谢!
whatkindu 2002-12-24
  • 打赏
  • 举报
回复
抱歉忘了解释了,PS是PhotoShop
weibz0525 2002-12-24
  • 打赏
  • 举报
回复
帮你up吧,我只想知道一下色阶的概念。呵呵
weibz0525 2002-12-24
  • 打赏
  • 举报
回复
听了hdaq一言茅塞顿开,不过脑子今天有点晕晕啊,明天编程实现了.
hdaq 2002-12-24
  • 打赏
  • 举报
回复
其实你看一下PS自带的Help中关于色阶调整的说明你就可以猜测出它的意思来。

//Help

例如,假定您要通过当前仅为 0-233 范围的象素提高图象中的对比度。如果您将“输入色阶”白色三角形拖移到 233,233 或更高亮度值(图象的每个通道中)会被映射为 255,较低亮度值的象素会被映射为相应的较亮值。这样的重新映射会使图象变亮,提高高光区域中的对比度。

相反,假定您要降低图象中的对比度,如果将“输出色阶”白色三角形拖移到 220,225 亮度值的象素会被重新映射为 220,较低亮度值的象素会被映射为相应较暗值。这会使图象变暗,降低高光区域中的对比度。
您也可以直接将数值输入到“输出色阶”文本框。

//

由以上可以看出,色阶调整实际上就是RGB的拉伸,比如你“输入色阶”= 10 ~ 200,“输出色阶”= 50 ~ 240;则是将图象从10~200(小于10的按10处理,大于200的按200处理)拉伸到50~240,相信这个你应该回了吧,还有一个“中间调”灰度系数,不言而喻就是定位中间色调的位置,你可以使用也可以按默认的。

至于自动色阶,Help中说的也很清楚:
“自动色阶”命令以及“色阶”和“曲线”对话框中的“自动”按钮可自动执行等量的“色阶”滑块调整:它们将每个通道中的最亮和最暗象素定义为白色和黑色,然后按比例重新分配中间象素值。
whatkindu 2002-12-24
  • 打赏
  • 举报
回复
真的没有人知道?

13,873

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧