我原本的想法是,设置一个3维数组,维数是R,G,B值,所以这个数组是这样的array[byte,byte,byte] of word但是问题是,函数不允许有那么大的参数。那好,我现在改成对每一个 r,g,b 值 除以10, 然后 floor,我的意思是忽略细微的颜色差别,结果数组就变成array[0..25,0..25,0..25] of word然后用Scanline取每一点的颜色,相应的改变数组里的值(就是在相应的维数那里加1而已)。这部分已经最大优化了,可以跳过。最后我还要再次检索一次那个三维数组,找到里面的最大值。再将维数提出来,变化一个颜色。这个值就是近似出现最多的那种颜色。这种方法我是创建了一个 thread 来做的,速度还可以接受。
只是效果不是太好,并不能找到最准确的值。而且,如果一张图象,背景都是近似白的,但是人物有很多暗色,结果得出来的还是类似黑色的值。我在网上也搜索了很久,找不到有什么可以参考的信息。所以来这里请教,请各位有自己想法的给点提示吧,谢谢!
只是效果不是太好,并不能找到最准确的值。而且,如果一张图象,背景都是近似白的,但是人物有很多暗色,结果得出来的还是类似黑色的值。我在网上也搜索了很久,找不到有什么可以参考的信息。所以来这里请教,请各位有自己想法的给点提示吧,谢谢!
是可以的。大不了定义一个全局变量。从速度上考虑,除以10再floor速度会比较慢。
建议采用移位操作。SHR会快很多。采用两个个变量,记录当前最多的一种颜色和当前最多的一种颜色的出现次数。
这样可以减少最后的一次检索工作。背景都是近似白的,但是人物有很多暗色
有可能出现次数最多的就是这种暗色呀?
var
a:array[..] of word;
MaxCountColor:integer; MaxCount :integer;MaxCount :=0;
MaxCountColor := 0;
for i:=0 to ....
begin
a[r,g,b] := a[r,g,b] +1;
if a[r,g,b] > MaxCount then
begin
MaxCountColor := r shl 16 + g shl 8 + b;
MaxCount := a[r,g,b]; //这就是最大数量的颜色和最大数量
end;
减少一倍的效果可能更好一些。
就是说,采用[8,8,8]的效果试试看。建议采用2的倍数,然后移位操作会快很多。上面的代码没有认真考虑,不过你应该能懂。
array[byte,byte,byte] of word;
定义在局部变量或者作为函数的参数(要先用type定义类型)都可以。
我在我的机器上测试通过。
type
tflagArray = array [byte,byte,byte] of integer;然后在函数里 var
flags:tflagArray;还是会出错。我个人就一直觉得是不行的,即使可以,也不是一个好方法。因为所有函数入口出都会根据子变量的多少在 stack 上预留空间,如果定义一个那么的空间,对 stack 来说太危险,很容易 overflow。所以,还是算了。你的算法很不错。不过我改成了 [17,17,17], 代码也改成 for...
r:=rgbtRed shr 4;
b:=rgbtBlue shr 4;
g:=rgbtGreen shr 4;
inc(flags[r,g,b]); if (flags[r,g,b]>MaxCount) then begin
MaxCountColor := RGB(rgbtRed,rgbtGreen,rgbtBlue);
MaxCount:=flags[r,g,b];
end;这样的结果比较正常,而且最后的颜色也绝对是图片上的色。