图像颜色快速优化提取算法???

Seedling 2002-03-06 08:30:14
从一真彩色图像(W×H)中已获得各像素点的颜色数组rgbcol(W×H-1) as long,假设该数组中不同的颜色数在256个以上,请问如何快速并优化提取其中<=256个不同颜色?
要求: 用它来创建逻辑调色板并保存的256色图像与原真彩色图像相比失真最小。
...全文
294 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
Seedling 2002-03-12
  • 打赏
  • 举报
回复
看来没人会了!
结账!
zyl910 2002-03-11
  • 打赏
  • 举报
回复
To Seedling(叶子):
看来没人会了!
结账吧!
zyl910 2002-03-09
  • 打赏
  • 举报
回复
up
Seedling 2002-03-09
  • 打赏
  • 举报
回复
up
zyl910 2002-03-08
  • 打赏
  • 举报
回复
http://www.microsoft.com&item=member&login=www.21code.com&passwordhash=1011959112&downloadsrv=china_bjtelcom&file=&+@www.21code.com/codebase/go.php?data=dmJjb2RlL3ZiY2RncnBoL0Zhc3Rlc3RHcmFwaGljYWxFZmZlY3RzSW5QVVJFVkJVUEQuemlw
一个图像处理的例子,可能能给你些帮助。
Seedling 2002-03-08
  • 打赏
  • 举报
回复
up
秋雨 2002-03-08
  • 打赏
  • 举报
回复
<256个组合恐怕比较少吧?
Seedling 2002-03-08
  • 打赏
  • 举报
回复
谢谢zyl910(910:分儿,我来了!) ,先给50分。


256色特定调色板的抖动算法,对拥有大量不同颜色的图片相对比较适宜,但对不同颜色个数<=256个或稍多或存在较多的颜色比较接近时,此法处理的图像质量与应该获得的相比显得差了。
对大图片的处理速度是比较快的(用GetDIBits()函数获取图像颜色数组,经运算后由SetDIBits()或StretchDIBits()生成图像)。


我的算法思路:

1、用GetDIBits()函数获取图像颜色数组
2、用快速升序排序
3、数组中去掉各重复颜色的值(同种颜色只保留一个)而得到一新颜数组
4、判别颜色数组中的颜色个数,若<=256 直接以此数据组成256色逻辑调色板(不足256个用0补全)
5、否则用合适的方法去除数中相对比较接近的颜色使新获得数组颜色数在230~256个,以此数据组成256色逻辑调色板(不足 256个用0补全)

此法对不同颜色数相对256个而言不很多或图片尺寸不太大时,处理后的图像质量较好,速度也较快。

希望各vb爱好者谈谈你的思路或算法!
zyl910 2002-03-07
  • 打赏
  • 举报
回复

Private Sub HSBar1_Change()
PicView1.Left = -HSBar1.Value
End Sub

Private Sub HSBar1_Scroll()
HSBar1_Change
End Sub

Private Sub VSBar1_Change()
PicView1.Top = -VSBar1.Value
End Sub

Private Sub VSBar1_Scroll()
VSBar1_Change
End Sub

Private Sub HSBar2_Change()
PicView2.Left = -HSBar2.Value
End Sub

Private Sub HSBar2_Scroll()
HSBar2_Change
End Sub

Private Sub VSBar2_Change()
PicView2.Top = -VSBar2.Value
End Sub

Private Sub VSBar2_Scroll()
VSBar2_Change
End Sub

Private Sub ScrollSize()
If PicRect1.ScaleWidth < PicView1.Width Then
HSBar1.Enabled = True
HSBar1.LargeChange = PicRect1.ScaleWidth
HSBar1.Max = PicView1.Width - PicRect1.ScaleWidth
If HSBar1.Value > HSBar1.Max Then HSBar1.Value = HSBar1.Max

Else
HSBar1.Value = 0
HSBar1.Enabled = False

End If

If PicRect1.ScaleHeight < PicView1.Height Then
VSBar1.Enabled = True
VSBar1.LargeChange = PicRect1.ScaleHeight
VSBar1.Max = PicView1.Height - PicRect1.ScaleHeight
If VSBar1.Value > VSBar1.Max Then VSBar1.Value = VSBar1.Max

Else
VSBar1.Value = 0
VSBar1.Enabled = False

End If

If PicRect2.ScaleWidth < PicView2.Width Then
HSBar2.Enabled = True
HSBar2.LargeChange = PicRect2.ScaleWidth
HSBar2.Max = PicView2.Width - PicRect2.ScaleWidth
If HSBar2.Value > HSBar2.Max Then HSBar2.Value = HSBar2.Max

Else
HSBar2.Value = 0
HSBar2.Enabled = False

End If

If PicRect2.ScaleHeight < PicView2.Height Then
VSBar2.Enabled = True
VSBar2.LargeChange = PicRect2.ScaleHeight
VSBar2.Max = PicView2.Height - PicRect2.ScaleHeight
If VSBar2.Value > VSBar2.Max Then VSBar2.Value = VSBar2.Max

Else
VSBar2.Value = 0
VSBar2.Enabled = False

End If

End Sub
zyl910 2002-03-07
  • 打赏
  • 举报
回复

Private Sub CmdStart_Click()
PicView2.Width = PicView1.Width
PicView2.Height = PicView1.Height
Me.MousePointer = vbHourglass
DoEvents

Dim LightnessMatrix(0 To &HFF) As Byte
Dim TempArray() As Variant
Dim ColorIndex(0 To &HFF) As Long
Dim TempC As Long
Dim TempByt As Byte
Dim R As Byte, G As Byte, B As Byte
Dim R1 As Byte, G1 As Byte, B1 As Byte
Dim TemphDC1 As Long, TemphDC2 As Long
Dim TempMaxX As Long, TempMaxY As Long
Dim TempInt As Integer
Dim I As Long, J As Long, K As Long

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

'设置调色板。R2G3B3格式
For I = 0 To 7
For J = 0 To 7
For K = 0 To 3
ColorIndex(I * &H20 + J * 4 + K) = RGB(K * &HFF / 3, J * &HFF / 7, I * &HFF / 7)
Next K
Next J
Next I

TempMaxX = PicView2.ScaleX(PicView2.ScaleWidth, PicView2.ScaleMode, vbPixels) - 1
TempMaxY = PicView2.ScaleY(PicView2.ScaleHeight, PicView2.ScaleMode, vbPixels) - 1
TemphDC1 = PicView1.hdc
TemphDC2 = PicView2.hdc

For I = 0 To TempMaxY
For J = 0 To TempMaxX
TempC = GetPixel(TemphDC1, J, I)

R = TempC And &HFF
G = (TempC And &HFF00&) \ &H100
B = (TempC And &HFF0000) \ &H10000

R1 = R * 3 \ &HFF
G1 = G * 7 \ &HFF
B1 = B * 7 \ &HFF
TempByt = LightnessMatrix((I And &HF) * &H10 + (J And &HF))

TempInt = R1 * &HFF \ 3
If TempInt <> R Then
R = R1 + (((R - TempInt) * &H100 \ ((R1 + 1) * &HFF \ 3 - TempInt) > TempByt) And 1)
Else
R = R1
End If
TempInt = G1 * &HFF \ 7
If TempInt <> G Then
G = G1 + (((G - TempInt) * &H100 \ ((G1 + 1) * &HFF \ 7 - TempInt) > TempByt) And 1)
Else
G = G1
End If
TempInt = B1 * &HFF \ 7
If TempInt <> B Then
B = B1 + (((B - TempInt) * &H100 \ ((B1 + 1) * &HFF \ 7 - TempInt) > TempByt) And 1)
Else
B = B1
End If

Call SetPixelV(TemphDC2, J, I, ColorIndex(B * &H20 + G * &H4 + R))

Next J
Next I

PicView2.Refresh

ScrollSize
Me.MousePointer = vbDefault

End Sub

Private Sub Form_Load()
CmdLoad.Top = Me.ScaleY(1, vbPixels)
CmdStart.Top = CmdLoad.Top + CmdLoad.Height + Me.ScaleY(1, vbPixels)
CmdSave.Top = CmdStart.Top + CmdStart.Height + Me.ScaleY(1, vbPixels)

PicRect1.Left = 0
PicRect1.Top = 0
PicRect2.Top = 0

PicView1.Left = 0
PicView1.Top = 0
PicView2.Left = 0
PicView2.Top = 0

HSBar1.Height = Me.ScaleY(16, vbPixels)
HSBar2.Height = HSBar1.Height
VSBar1.Width = Me.ScaleX(16, vbPixels)
VSBar2.Width = VSBar1.Width

CDlgLoad.Filter = "图形文件(*.bmp;*.jpg;*.gif;*.wmf;*.ico;*.cur)|*.bmp;*.jpg;*.gif;*.wmf;*.ico;*.cur|所有文件(*.*)|*.*"
CDlgLoad.FilterIndex = 1
CDlgLoad.Flags = cdlOFNFileMustExist Or cdlOFNHideReadOnly Or cdlOFNPathMustExist

CDlgSave.Filter = "Windows位图(*.bmp)|*.bmp|所有文件(*.*)|*.*"
CDlgSave.FilterIndex = 1
CDlgSave.Flags = cdlOFNHideReadOnly Or cdlOFNPathMustExist Or cdlOFNOverwritePrompt

End Sub

Private Sub Form_Resize()
If Me.WindowState = vbMinimized Then Exit Sub

On Error Resume Next

CmdLoad.Left = (Me.ScaleWidth - CmdLoad.Width) / 2
CmdStart.Left = CmdLoad.Left
CmdSave.Left = CmdLoad.Left

PicRect1.Width = CmdLoad.Left - VSBar1.Width
PicRect1.Height = Me.ScaleHeight - HSBar1.Height
PicRect2.Left = CmdLoad.Left + CmdLoad.Width
PicRect2.Width = PicRect1.Width
PicRect2.Height = PicRect1.Height

HSBar1.Left = PicRect1.Left
VSBar1.Top = PicRect1.Top
HSBar1.Top = PicRect1.Height
HSBar1.Width = PicRect1.Width
VSBar1.Left = PicRect1.Width
VSBar1.Height = PicRect1.Height

HSBar2.Left = PicRect2.Left
VSBar2.Top = PicRect2.Top
HSBar2.Top = HSBar1.Top
HSBar2.Width = HSBar1.Width
VSBar2.Left = PicRect2.Left + PicRect2.Width
VSBar2.Height = VSBar1.Height

On Error GoTo 0

ScrollSize

End Sub
zyl910 2002-03-07
  • 打赏
  • 举报
回复
Color256.vbp
====================================================================
Type=Exe
Form=FrmColor256.frm
Reference=*\G{00020430-0000-0000-C000-000000000046}#2.0#0#..\..\..\..\..\..\WINDOWS\SYSTEM\stdole2.tlb#OLE Automation
Object={F9043C88-F6F2-101A-A3C9-08002B2F49FB}#1.2#0; COMDLG32.OCX
IconForm="FrmColor256"
Startup="FrmColor256"
ExeName32="Color256.exe"
Command32=""
Name="Color256"
HelpContextID="0"
CompatibleMode="0"
MajorVer=1
MinorVer=0
RevisionVer=0
AutoIncrementVer=0
ServerSupportFiles=0
VersionCompanyName="91"
CompilationType=0
OptimizationType=0
FavorPentiumPro(tm)=0
CodeViewDebugInfo=0
NoAliasing=0
BoundsCheck=0
OverflowCheck=0
FlPointCheck=0
FDIVCheck=0
UnroundedFP=0
StartMode=0
Unattended=0
Retained=0
ThreadPerObject=0
MaxNumberOfThreads=1



FrmColor256.frm
====================================================================
VERSION 5.00
Object = "{F9043C88-F6F2-101A-A3C9-08002B2F49FB}#1.2#0"; "COMDLG32.OCX"
Begin VB.Form FrmColor256
Caption = "256色抖动算法"
ClientHeight = 3195
ClientLeft = 60
ClientTop = 345
ClientWidth = 4680
LinkTopic = "Form1"
LockControls = -1 'True
ScaleHeight = 3195
ScaleWidth = 4680
StartUpPosition = 3 '窗口缺省
Begin MSComDlg.CommonDialog CDlgSave
Left = 2130
Top = 2400
_ExtentX = 847
_ExtentY = 847
_Version = 393216
CancelError = -1 'True
End
Begin MSComDlg.CommonDialog CDlgLoad
Left = 2130
Top = 0
_ExtentX = 847
_ExtentY = 847
_Version = 393216
CancelError = -1 'True
End
Begin VB.CommandButton CmdStart
Caption = "运算"
Height = 540
Left = 2190
TabIndex = 8
Top = 1080
Width = 300
End
Begin VB.CommandButton CmdSave
Caption = "保存"
Height = 540
Left = 2190
TabIndex = 7
Top = 1650
Width = 300
End
Begin VB.CommandButton CmdLoad
Caption = "读取"
Height = 540
Left = 2190
TabIndex = 6
Top = 510
Width = 300
End
Begin VB.HScrollBar HSBar2
Height = 225
Left = 2640
TabIndex = 5
Top = 2940
Width = 1845
End
Begin VB.HScrollBar HSBar1
Height = 255
Left = 30
TabIndex = 4
Top = 2940
Width = 2055
End
Begin VB.VScrollBar VSBar2
Height = 2895
Left = 4440
TabIndex = 3
Top = 60
Width = 225
End
Begin VB.VScrollBar VSBar1
Height = 2775
Left = 1800
TabIndex = 2
Top = 30
Width = 225
End
Begin VB.PictureBox PicRect2
Height = 2925
Left = 2640
ScaleHeight = 191
ScaleMode = 3 'Pixel
ScaleWidth = 119
TabIndex = 1
Top = 0
Width = 1845
Begin VB.PictureBox PicView2
AutoRedraw = -1 'True
AutoSize = -1 'True
BackColor = &H00C0C0FF&
BorderStyle = 0 'None
Height = 975
Left = 150
ScaleHeight = 65
ScaleMode = 3 'Pixel
ScaleWidth = 59
TabIndex = 9
Top = 120
Width = 885
End
End
Begin VB.PictureBox PicRect1
Height = 2925
Left = 0
ScaleHeight = 191
ScaleMode = 3 'Pixel
ScaleWidth = 119
TabIndex = 0
Top = 0
Width = 1845
Begin VB.PictureBox PicView1
AutoRedraw = -1 'True
AutoSize = -1 'True
BackColor = &H00C0C0FF&
BorderStyle = 0 'None
Height = 975
Left = 240
ScaleHeight = 65
ScaleMode = 3 'Pixel
ScaleWidth = 59
TabIndex = 10
Top = 150
Width = 885
End
End
End
Attribute VB_Name = "FrmColor256"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Option Explicit
Private Declare Function GetPixel Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long) As Long
Private Declare Function SetPixelV Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal crColor As Long) As Long

Private Sub CmdLoad_Click()
On Error GoTo ErrLoad

CDlgLoad.ShowOpen

Set PicView1.Picture = LoadPicture(CDlgLoad.FileName)

On Error GoTo 0

ScrollSize

Exit Sub

ErrLoad:
If Err.Number = cdlCancel Then
Else
MsgBox Err.Description, vbCritical, Err.Number
End If

End Sub

Private Sub CmdSave_Click()
On Error GoTo ErrSave

CDlgSave.ShowSave

SavePicture PicView2.Picture, CDlgSave.FileName

On Error GoTo 0

Exit Sub

ErrSave:
If Err.Number = cdlCancel Then
Else
MsgBox Err.Description, vbCritical, Err.Number
End If

End Sub
Seedling 2002-03-06
  • 打赏
  • 举报
回复
up
Seedling 2002-03-06
  • 打赏
  • 举报
回复
to: zyl910(910:分儿,我来了!)

如果用256色系统调色板或未优化取色创建的256色逻辑调色板来用,对某些图像严重失真,不知256色特定调色板的抖动算处理法速度和效果如何?能否提供,在此先谢了!

dxd59928@mail.nbptt.zj.cn
zyl910 2002-03-06
  • 打赏
  • 举报
回复
我只知道256色特定调色板的抖动算法。
daryl715 2002-03-06
  • 打赏
  • 举报
回复
不清楚,帮你up

7,763

社区成员

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

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