QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 6124|回复: 0
打印 上一主题 下一主题

用C++ Builder对图像进行特殊效果处理

[复制链接]
字体大小: 正常 放大
韩冰        

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

跳转到指定楼层
1#
发表于 2005-1-26 12:49 |只看该作者 |倒序浏览
|招呼Ta 关注Ta
<>
& @3 ~4 ]; p1 q! ^周新栋
4 F. }6 j1 m- U) t! ] </P>9 [" D( W3 M8 h9 w7 [
<>     </P>: u* h+ M# E# x1 _$ a& W& A
<>( e6 I! O0 T8 l9 Z2 I+ ^4 U* a: ~
--- 在Windows编程中图像处理相对比较复杂,好在C++ Builder提供了一些图形类,它们通过对Windows中的图形对象进行包装,从而大大简化了图像操作的难度。下面就通过对图像进行柔化、锐化、浮雕效果等几个特殊效果处理来具体说明一下。 </P>' w# w" g% [; j, {/ m9 r6 D
<>---- 一、准备工作 位图图形实际上是像素的二维数组,它记录了每个像素的颜色信息,而TCanvas类提供了Pixels属性,用它可以存取指定像素的颜色值,通过这个属性将位图图形的部分或全部像素的颜色值进行相应的变换处理,就可以实现图像的特殊效果处理。在Windows中颜色是根据红、绿、蓝三种颜色的饱和度来定义的,在这里我们要将像素颜色值的红、绿、蓝分量从像素值中分离出来,分别加以保存,所以需要定义一个结构来存放颜色分量: </P>
7 z4 f2 g) e) N- J7 l<>struct rgb_str{
( ~4 @' n) G4 l# d4 V* [/ @9 Q: Cunsigned char r_color;/ }& I$ R/ [5 R
unsigned char g_color;
* K4 \5 B: o* f4 m' Cunsigned char b_color;};
. u, \3 H- y" E" Grgb_str rgb[2000][2000];</P>
) n" J+ R9 ~3 G7 |0 w( _  M<>建立全局变量:Graphics::TBitmap *bitmap;
+ E1 N& \- d$ V/ {% r4 w//用来存放变换后的位图
* [9 n) c* C! R9 sint i,j,width,height;</P>
4 t3 ?4 f* j) L1 M# }, @<>---- 在窗体上放置一个TImage组件和OpenPictureDialog组件,将TImage的AutoSize属性设为true,将OpenPictureDialog的Filter设为*.bmp。当用户选择Open命令后,打开相应的对话框,让用户选择要处理的图像文件,然后程序将图像的所有像素的颜色分量保存到rgb数组中: </P>( G- |* ~( H% s  }4 e
<>void __fastcall TForm1::mnuFileOpenClick6 q/ ?$ Q, W/ q# h
(TObject *Sender)' t/ a1 E* z9 m2 Z' N4 q: F# R
{1 c' d: {4 E' Q
TColor color;
: z# ~$ Y) X* r1 S3 U2 n) Mif(OpenPictureDialog1- &gt;Execute()){
8 p( w+ D8 X  g* R0 s$ ^# }9 ZImage1- &gticture-&gt;LoadFromFile
+ U& w/ T$ \, Z4 c1 k        (OpenPictureDialog1- &gt;FileName);% G: l0 e% S1 Y3 c) ]  u1 i4 f, ?
width=Image1- &gticture- &gt;Width;
: X# s6 m; x  I4 `, m9 A$ Z, hheight=Image1-&gticture-&gt;Height;2 Q$ O# p; j- I- Q5 j
for(i=0;i&lt; width-1;i++)
" s2 m: l/ U# P9 i( Vfor(j=0;j&lt; height-1;j++){
# |# K" b0 q, o4 G1 h$ ]color=Image1- &gt;Canvas-&gtixels[j];
" y; k2 E! V$ I/ v6 G" Ergb[j].r_color=GetRValue(color);
# L/ M  L4 B* l- \' M: q; ~rgb[j].g_color=GetGValue(color);5 e$ g9 Z' c# {2 @* d& `% y  U
rgb[j].b_color=GetBValue(color);+ L& p4 H/ F  f/ H0 c! ^6 }' a
}
# J5 V9 b. ~' \4 Hbitmap=new Graphics::TBitmap;
4 F) T1 z% A+ Ibitmap- &gt;Width=width;
& p. K% `0 {, F0 P( p- kbitmap- &gt;Height=height;* Z% f* K, Z/ t8 m) U7 g
}
8 K% q4 f/ R- Z}</P>) }/ I1 N' P- j# P
<>
  X( T5 H2 w8 l2 b  x4 I, }---- 二、图像的柔化处理 </P>
2 R7 i+ N$ E/ L<>---- 柔化就是对图像进行平滑处理,减少相邻像素间的颜色差别,一般选用3*3像素块,将中间的像素值改成这9个像素的平均像素值,从而达到柔化效果。其代码如下: </P>5 M% @+ Q) ~! G$ Q' d
<>void __fastcall TForm1::btnSmoothClick9 x% \* S( V: [# ^4 E
(TObject *Sender)
0 J$ C' F; D9 D$ H2 X, p{
8 s0 y! \+ `  E4 d; ~int red,green,blue;
; I. A! O: G0 [: r1 b% dfor(i=1;i&lt; width-2;i++)
+ T% ?2 }5 v. q7 u3 `8 K( ^5 i# ufor(j=1;j&lt; height-2;j++){
; S. n  e' t8 x9 v4 Rred=rgb[i-1][j-1].r_color+rgb[j-1].r
$ w" E* U% K# U* \% i9 d        _color+rgb[i+1][j-1].r_color+
$ `1 d* U- B3 M: H% s6 Lrgb[i-1][j].r_color+rgb[j].r
3 g8 ], j9 G. P( r            _color+rgb[i+1][j].r_color+</P>
2 d: h: G! w/ a7 S5 \/ Z<>            rgb[i-1][j+1].r_color+rgb[j+1].r! q. _4 r' }0 h
            _color+rgb[i+1][j+1].r_color;! n$ }# o4 h: n7 d. n$ Q
green=rgb[i-1][j-1].g_color+rgb[j-1].g$ Y+ v4 `0 j; m' _
        _color+rgb[i+1][j-1].g_color+
, _/ w' z6 u! C" E4 }5 Mrgb[i-1][j].g_color+rgb[j].g' G: ]* ?6 E+ R7 _! {
            _color+rgb[i+1][j].g_color+4 ~  ]- d. V) h4 T# l- y+ Z
rgb[i-1][j+1].g_color+rgb[j+1].g
) x7 d4 U. i! k. ]" l/ S            _color+rgb[i+1][j+1].g_color;
; O7 @( n) G5 N0 H4 |+ rblue=rgb[i-1][j-1].b_color+rgb[j-1].b* E, \/ g3 V1 w
        _color+rgb[i+1][j-1].b_color+
+ s$ Y/ L4 d3 r7 V* argb[i-1][j].b_color+rgb[j].b
: |8 y3 `9 ?; L! J0 {            _color+rgb[i+1][j].b_color+# O3 O3 {% i5 Z1 G* S  D
rgb[i-1][j+1].b_color+rgb[j+1].b
3 q2 k, L6 `" A& L$ a) |            _color+rgb[i+1][j+1].b_color;
. T* w* w* w0 Z6 O* B& a& Q* ~: Cbitmap- &gt;Canvas- &gtixels[j]
3 G- y% ~. w$ M; h        =RGB(red/9,green/9,blue/9);+ N% m  W2 Y* m, W
}1 M5 X- R; M( V/ O3 O
Image1- &gticture- &gt;Bitmap- &gt;Assign(bitmap);1 {7 ^( I. ~; x8 ]) _0 i* ^
}</P>
5 F3 t3 ?- y2 s2 }5 @  J. U7 x<>---- 三、图像的锐化处理 </P>
; P. }9 g- ^8 F' y$ D<>---- 图像的锐化处理正好与柔化处理相反,它的目的是突出图像的变化部分,这里采用的算法是将要处理的像素与它左对角线的像素之间的差值乘上一个锐化度数,然后再加上原先的像素值:new_value=original_value+degree*difference,你可以通过改变degree的值来调节锐化效果。这里需要注意的是得到的像素新值可能会超出颜色值的有效范围(0-255),所以程序要检验结果的有效性,为此需定义两个函数: </P>5 H$ \' n: T- |4 `
<>int min(int value1,int value2)/ |# S) i% V1 S9 |
{
1 @5 [& f8 D5 X  \3 qif(value1 &gt;value2)return value2;* z* J/ M1 F$ k+ }
else return value1;
9 x2 s  p. \! ~9 l% E9 l}
6 y& |1 f6 Y6 l( c( t- \% ^int max(int value1,int value2)
3 s  V5 q5 S& d! o. h4 e6 n{: f  x$ u. s) b9 `
if(value1 &gt;value2)return value1;% u+ {2 ~$ p" l6 y. Z2 \& l
else return value2;
9 W% A& P: D# r: r) C. T8 A4 v}</P>
: n7 O% K8 g& X( Y: a% t6 w+ I<>锐化处理的代码如下:</P>
2 E' s& E' N& k: i<>void __fastcall TForm1::btnSharpeClick2 R# f  Q. g; z- v) R2 C
(TObject *Sender)! _4 |, a1 S8 q. G$ D/ }6 \
{
/ s* Z7 K9 x* g( ^float degree=0.3;
! H. i; P, M" ~int red,green,blue;
. M6 E3 A* T( v' x$ vfor(i=1;i&lt; width-1;i++): {% `7 J' _  X
for(j=1;j&lt; height-1;j++){8 ?! r& E4 a. @: G. z9 X
red=rgb[j].r_color+degree*(rgb[j].r; E  E! [  w& o7 l
        _color-rgb[i-1][j-1].r_color);: q/ d- r/ P9 x# y
green=rgb[j].g_color+degree*(rgb[j].g8 G4 v. t4 ?! W$ N8 {; f" W
        _color-rgb[i-1][j-1].g_color);
% `* p/ Q6 y' E' x; Kblue=rgb[j].b_color+degree*(rgb[j].b# w* ~( H+ s5 m2 f1 Y9 F2 ]
        _color-rgb[i-1][j-1].b_color);
$ a$ d5 ]! T1 Q# k. \7 ~" k' ored=min(255,max(0,red));8 D9 D" w7 l4 V& {% r( s" I+ ?9 O
green=min(255,max(0,green));, z( u; T" G# e2 f5 {' r! J) S, [
blue=min(255,max(0,blue));
2 W4 d0 X- ^$ F  P) V6 z4 Kbitmap- &gt;Canvas-&gtixels[j]=RGB1 [/ h) s5 O* ?, x
        (red,green,blue);4 H( D5 R1 p$ \" S- k
}8 v8 _& q* ^6 F( g. g2 q/ }: Q' u
Image1- &gticture- &gt;Bitmap- &gt;Assign(bitmap);( p' n% [9 t3 x! b' ?! I
}</P>% F) v$ y/ Q# p3 [5 G8 Z. }3 [
<>$ `8 ?6 q4 Z2 A( ^# d3 E9 G3 b: K1 `7 ]
---- 四、图像的浮雕效果实现 </P>
. T' e& f7 I+ p) z' N! g<>---- 浮雕效果就是只将图像的变化部分突出出来,而相同颜色部分则被淡化,使图像出现纵深感,从而达到浮雕效果,这里采用的算法是将要处理的像素取值为与处于对角线上的另一个像素间的差值,这样只有颜色变化区才会出现色彩,而颜色平淡区因差值几乎为零则变成黑色,你可以通过加上一个常量来增加一些亮度:new_value=difference+const_value,具体代码如下: </P>4 e# h1 q+ a: |6 `
<>void __fastcall TForm1::btnEmbossClick
2 T1 ]  ^( x3 M& j  m2 B; Z" T$ r(TObject *Sender)
, h6 @% L+ ]8 p& n7 O: k{" y& @4 |$ F* J6 N# x" u
int red,green,blue;
7 m  A2 y& \3 Dconst int const_value=128;
- E( A$ a% ?3 Lfor(i=0;i&lt; width-2;i++)+ L; s( i! d# r1 C" b
for(j=0;j&lt; height-2;j++){
% w. \  X, ?; v8 yred=abs(rgb[j].r_color-rgb[i+1][j+1].r
3 ~+ Q" |/ S' n9 n* }+ B& P; N        _color+const_value);
- X9 E9 j5 _  R* S0 ?green=abs(rgb[j].g_color-rgb[i+1][j+1].g6 x$ A4 R: |) b0 R8 K) U
        _color+const_value);
: u8 u/ ?& Q; q2 c- bblue=abs(rgb[j].b_color-rgb[i+1][j+1].b_
: \5 P# \8 T% M, A: _        color+const_value);
5 v+ C0 n0 T' S+ Jbitmap- &gt;Canvas- &gtixels[j]=RGB6 ^$ L$ O0 `- S$ U  O- V9 A/ T
        (red,green,blue);
+ e3 N; J3 U  R1 Y) l' B}
, ]% u6 j/ C& d8 @6 T1 n- \7 EImage1- &gticture- &gt;Bitmap- &gt;Assign(bitmap);
! A2 ?: O# m7 N+ c: i3 c}</P>- y1 N0 e1 P, A& u  \. t
<P>---- 上面介绍了图像处理中的几个常见操作,所采用的算法相对比较简单,感兴趣的朋友可以举一返三,通过改进上述算法,达到更好的特殊效果。以上代码在C++ Builder3、Pwin98下编译、运行通过。 : e6 M! F* q5 ^' T
</P>
zan
转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
您需要登录后才可以回帖 登录 | 注册地址

qq
收缩
  • 电话咨询

  • 04714969085
fastpost

关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

手机版|Archiver| |繁體中文 手机客户端  

蒙公网安备 15010502000194号

Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

GMT+8, 2026-4-20 12:40 , Processed in 0.462427 second(s), 52 queries .

回顶部