部署OV7670录像头采集到的数额是RGB565,查询了许多素材后

  学习博客:http://lhtao31.blog.163.com/blog/static/2972647020103814044158/

  学习博客:http://lhtao31.blog.163.com/blog/static/2972647020103814044158/

Android 上有一个比较短小精悍的库 ——
Palette,整个库只有PaletteTargetColorCutQuantizer多个公文,
功用是从图像中领取非凡的颜料提供UI使用。

  如今在求学调试视频头,配置OV7670视频头采集到的数据是RGB565,移植旁人的代码,从ZYNQ移植到Basys3,VGA输出引脚需要又RGB565转到RGB444,我利用分别取RGB565三重量高位的不二法门,最后展现输出,视频图像会变得更模糊,这是出于在转换的时候去掉低位会损失精度。而OV7670的图像采集效果也是平时,所未来面会尝试配置OV7725,追求完美,达到更好的彰显效果。查询了成千上万素材后,知道了这是何等原因,下边我自己查阅的素材整理一下,将来查询起来方便。

  目前在攻读调试录像头,配置OV7670视频头采集到的数量是RGB565,移植外人的代码,从ZYNQ移植到Basys3,VGA输出引脚需要又RGB565转到RGB444,我动用分别取RGB565三轻重高位的不二法门,最后展现输出,视频图像会变得更模糊,这是出于在转移的时候去掉低位会损失精度。而OV7670的图像采集效果也是通常,所将来面会尝试配置OV7725,追求面面俱到,达到更好的来得效果。查询了无数资料后,知道了这是哪些原因,下边我自己查阅的素材整理一下,将来查询起来方便。

如何选拔

导入看重包

implementation 'com.android.support:palette-v7:27.0.2'

简单利用

//需要传入要提取的图片 bitmap
val builder = Palette.from(bitmap)
builder.generate(Palette.PaletteAsyncListener { palette ->
     /**
     * palette.getVibrantSwatch();       //获取到充满活力的色调
     * palette.getDarkVibrantSwatch();    //获取充满活力的黑
     * palette.getLightVibrantSwatch();   //获取充满活力的亮
     * palette.getMutedSwatch();          //获取柔和的色调
     * palette.getDarkMutedSwatch();     //获取柔和的黑
     * palette.getLightMutedSwatch();   //获取柔和的亮
     */
    //获取color值
    val swatch: Palette.Swatch? = palette.lightVibrantSwatch
    val color = swatch.rgb
    }
})

如上代码所示,提取图片上的颜色需要传入 bitmap,Palette
默认给了6种提取色调的档次。

1 /* vga_red   <= frame_pixel[15:11];
2 vga_green <= frame_pixel[10:5];
3 vga_blue  <= frame_pixel[4:0]; */
4 vga_red   <= frame_pixel[15:12];
5 vga_green <= frame_pixel[10:7];
6 vga_blue  <= frame_pixel[4:1];
1 /* vga_red   <= frame_pixel[15:11];
2 vga_green <= frame_pixel[10:5];
3 vga_blue  <= frame_pixel[4:0]; */
4 vga_red   <= frame_pixel[15:12];
5 vga_green <= frame_pixel[10:7];
6 vga_blue  <= frame_pixel[4:1];

源码解析

Palette有二种开头化方法,也就是同步和异步方法,使用
Builder构造器时默认使用的是异步方法。每种模式下都足以提供调色板大小参数来设置

// 最好在线程中使用
// 默认调色板大小.
private static final int DEFAULT_CALCULATE_NUMBER_COLORS = 16;
Palette p = Palette.generate(bitmap);
//设置调色板大小numcolor
Palette p = Palette.generate(bitmap, numcolor);

// 内部使用AsyncTask
Palette.generateAsync(bitmap, new Palette.PaletteAsyncListener() {
    @Override
    public void onGenerated(Palette palette) {
        // palette为生成的调色板
    }
});
// 设置调色板大小
Palette.generateAsync(bitmap, numcolor, new Palette.PaletteAsyncListener() {
    @Override
    public void onGenerated(Palette palette) {
        // palette为生成的调色板
    }
})

当大家传入 Bitmap 后会首先对 Bitmap 做拍卖

// First we'll scale down the bitmap if needed
final Bitmap bitmap = scaleBitmapDown(mBitmap);

/**
 * Scale the bitmap down as needed.
 */
private Bitmap scaleBitmapDown(final Bitmap bitmap) {
    double scaleRatio = -1;

    if (mResizeArea > 0) {
        final int bitmapArea = bitmap.getWidth() * bitmap.getHeight();
        if (bitmapArea > mResizeArea) {
            scaleRatio = Math.sqrt(mResizeArea / (double) bitmapArea);
        }
    } else if (mResizeMaxDimension > 0) {
        final int maxDimension = Math.max(bitmap.getWidth(), bitmap.getHeight());
        if (maxDimension > mResizeMaxDimension) {
            scaleRatio = mResizeMaxDimension / (double) maxDimension;
        }
    }

    if (scaleRatio <= 0) {
        // Scaling has been disabled or not needed so just return the Bitmap
        return bitmap;
    }

    return Bitmap.createScaledBitmap(bitmap,
            (int) Math.ceil(bitmap.getWidth() * scaleRatio),
            (int) Math.ceil(bitmap.getHeight() * scaleRatio),
            false);
}

这么做为了防范 Bitmap
太大而致使总括消耗大量资源,默认的ResizeArea大小是112*112。

处理完 Bitmap 后通过 getPixelsFromBitmap(bitmap)
方法得到图像上的像素数组,然后经过 ColorCutQuantizer
来处理图像上色值。
拿到色值后,就足以将这多少个色值填入 Palette 中以便利用。

量化压缩与量化补偿

量化压缩与量化补偿

水彩量化算法

ColorCutQuantizer 是一个遵照 中位切分法(Median cut)
的颜色量化器,重要效用就是从彩色图像中领到其中的主旨颜色。

中位切分算法的法则很简短直接,将图像颜色看作是色彩空间中的长方体(VBox),从上马整个图像作为一个长方体起先,将RGB中最长的一派从颜色总计的中位数一切为二,使得到的多个长方体所含有的像素数量同样,重复上述手续,直到最终切分得到长方体的数额相当于主旨颜色数量截至。

图片 1

VBox.png

中间RGB最长的单向意思是,比如说在颇具像素中Red颜色的分布范围是(10-50),格林的遍布范围是(5-100),Blue的遍布范围是(0-200)。那么此时就相应以Blue为尺度,分成左右两堆,一堆的像素Blue值比中值小,另一堆像素Blue值比中值大。

唯独有时某些规则下VBOX里面的像素数量很少,比如实现过滤白色和藏粉红色时候,那时候就无法以看似二分法来切割VBOX,需要使用优先级队列举办排序,刚开端时这一队列以VBox仅以VBox所蕴藏的像素数作为优先级考量,当切分次数变多事后,将体积*饱含像素数作为优先级。

除此之外,算法中最重大的局部是总计色彩分布直方图。大家需要将三维空间中的任意一点对应到一维坐标中的整数,这样才能以最快地速度定位这一颜料。要是利用任何的24位音信,那么大家用来保存直方图的数高管度至少即便224=16777216,既然是要提取颜色主旨(或是颜色量化),我们能够将颜色由RGB各8位压缩至5位,这样数主管度只有215=32768:

量化压缩,举例:
24bit RGB888 -> 16bit RGB565 的转换

24bit RGB888
R7 R6 R5 R4 R3 R2 R1 R0 G7 G6 G5 G4 G3 G2 G1 G0 B7 B6 B5 B4 B3 B2 B1
B0

16bit RGB656
R7 R6 R5 R4 R3 G7 G6 G5 G4 G3 G2 B7 B6 B5 B4 B3

证实:在24bit上以8位为一组数据,在16bit上以5要么6为一组数据,
量化位数从8bit到5bit或6bit,取原8bit的高位,量化上做了削减,却损失了精度。

量化补偿,举例:16bit RGB565 -> 24bit RGB888 的变换

16bit RGB656 R4 R3 R2 R1 R0 G5 G4 G3 G2 G1 G0 B4 B3 B2 B1 B0

24ibt RGB888 R4 R3 R2 R1 R0 0 0 0 G5 G4 G3 G2 G1 G0 0 0 B4 B3 B2 B1 B0
0 0 0

24ibt RGB888 R4 R3 R2 R1 R0 R2 R1 R0 G5 G4 G3 G2 G1 G0 G1 G0 B4 B3 B2
B1 B0 B2 B1 B0

表明:第二行的 24bit RGB888
数据为转移后,未举行补充的数码,在精度上会有损失
其三行的 24bit RGB888 数据为经过量化补偿的多寡,对没有做了量化补偿


参考资料:
wiki
Median_cut

RGB565 与
RGB888的相互转换

量化压缩

量化压缩

24bit RGB888 -> 16bit RGB565 的转换

24bit RGB888 -> 16bit RGB565 的转换

24ibt RGB888 {R7 R6 R5 R4 R3 R2 R1 R0} {G7 G6 G5 G4 G3 G2 G1 G0} {B7 B6
B5 B4 B3 B2 B1 B0}

24ibt RGB888 {R7 R6 R5 R4 R3 R2 R1 R0} {G7 G6 G5 G4 G3 G2 G1 G0} {B7 B6
B5 B4 B3 B2 B1 B0}

16bit RGB565 {R7 R6 R5 R4 R3} {G7 G6 G5 G4 G3 G2} {B7 B6 B5 B4 B3}

16bit RGB565 {R7 R6 R5 R4 R3} {G7 G6 G5 G4 G3 G2} {B7 B6 B5 B4 B3}

量化位数从8bit到5bit或6bit,取原8bit的要职,量化上做了滑坡,却损失了精度。

量化位数从8bit到5bit或6bit,取原8bit的高位,量化上做了滑坡,却损失了精度。

量化补偿

量化补偿

16bit RGB565 -> 24bit RGB888 的转换

16bit RGB565 -> 24bit RGB888 的转换

16bit RGB565 {R4 R3 R2 R1 R0}{G5 G4 G3 G2 G1 G0}{B4 B3 B2 B1 B0}

16bit RGB565 {R4 R3 R2 R1 R0}{G5 G4 G3 G2 G1 G0}{B4 B3 B2 B1 B0}

24ibt RGB888 {R4 R3 R2 R1 R0 0 0 0 }{G5 G4 G3 G2 G1 G0 0 0 }{B4 B3 B2 B1
B0 0 0 0}

24ibt RGB888 {R4 R3 R2 R1 R0 0 0 0 }{G5 G4 G3 G2 G1 G0 0 0 }{B4 B3 B2 B1
B0 0 0 0}

24ibt RGB888 {R4 R3 R2 R1 R0 R2 R1 R0}{ G5 G4 G3 G2 G1 G0 G1 G0}{ B4 B3
B2 B1 B0 B2 B1 B0}

24ibt RGB888 {R4 R3 R2 R1 R0 R2 R1 R0}{ G5 G4 G3 G2 G1 G0 G1 G0}{ B4 B3
B2 B1 B0 B2 B1 B0}

其次行的 24bit RGB888 数据为转移后,未实行补充的数码,在精度上会有损失

其次行的 24bit RGB888 数据为转移后,未进行填空的数据,在精度上会有损失

 24bit RGB888 数据为经过量化补偿的数码,对没有做了量化补偿

 24bit RGB888 数据为通过量化补偿的多少,对没有做了量化补偿

总结

总结

量化压缩的格局:三个字——取高位

量化压缩的法子:三个字——取高位

量化补偿的办法

量化补偿的点子

  1. 将原数据填充至高位

  1. 将原数据填充至高位

  2. 对于没有,用原来数据的没有举办补给

  2. 对于没有,用原来数据的不比举行补偿

  3. 倘诺仍然有未填充的位,继续应用原来数据的不比举行循环补偿

  3. 一旦如故有未填充的位,继续运用原有数据的不如举办循环补偿

循环补偿的定义

循环补偿的定义

8bit RGB332 -> 24bit RGB888 的转换

8bit RGB332 -> 24bit RGB888 的转换

8bit RGB332{ R2 R1 R0} { G2 G1 G0} { B1 B0}

8bit RGB332{ R2 R1 R0} { G2 G1 G0} { B1 B0}

24bit RGB888 { R2 R1 R0 0 0 0 0 0 }{ G2 G1 G0 0 0 0 0 0} { B1 B0 0 0 0 0
0 0}

24bit RGB888 { R2 R1 R0 0 0 0 0 0 }{ G2 G1 G0 0 0 0 0 0} { B1 B0 0 0 0 0
0 0}

24bit RGB888 { R2 R1 R0 R2 R1 R0 0 0 }{ G2 G1 G0 G2 G1 G0 0 0 }{ B1 B0
B1 B0 0 0 0 0}

24bit RGB888 { R2 R1 R0 R2 R1 R0 0 0 }{ G2 G1 G0 G2 G1 G0 0 0 }{ B1 B0
B1 B0 0 0 0 0}

24bit RGB888 { R2 R1 R0 R2 R1 R0 R2 R1} { G2 G1 G0 G2 G1 G0 G2 G1} { B1
B0 B1 B0 B1 B0 0 0}

24bit RGB888 { R2 R1 R0 R2 R1 R0 R2 R1} { G2 G1 G0 G2 G1 G0 G2 G1} { B1
B0 B1 B0 B1 B0 0 0}

24bit RGB888 { R2 R1 R0 R2 R1 R0 R2 R1 }{ G2 G1 G0 G2 G1 G0 G2 G1 }{ B1
B0 B1 B0 B1 B0 B1 B0}

24bit RGB888 { R2 R1 R0 R2 R1 R0 R2 R1 }{ G2 G1 G0 G2 G1 G0 G2 G1 }{ B1
B0 B1 B0 B1 B0 B1 B0}

从如上转发可以看来,B分量举办了四轮补偿

从如上转账可以观察,B分量进行了四轮补偿

  举行这样的补偿,在做色彩格式转化的时候,可以明确的改进色彩效果,收缩精度上的损失。

  举办这样的补给,在做色彩格式转化的时候,可以明确的改善色彩效果,裁减精度上的损失。

  有时候,回过头来,会感谢自己,当初苦逼写的那么些博客没白写!

  有时候,回过头来,会感谢自己,当初苦逼写的那么些博客没白写!

  记得从前玩过两周Arduino,调试出了,实时收集引力传感器的数目到贝壳物联突显,还好我立刻做了有的笔记,以至于现在想用Arduino+FPGA做个类此外时候,很快就能上手调试了,所以,很感谢自己立时苦逼的写博客做速记!

  记得往日玩过两周Arduino,调试出了,实时采集重力传感器的多少到贝壳物联突显,还好我霎时做了有的笔记,以至于现在想用Arduino+FPGA做个类型的时候,很快就能上手调试了,所以,很感谢自己即刻苦逼的写博客做速记!

图片 2

图片 3

 

 

转载请申明出处:NingHeChuan(宁河川)

转载请声明出处:NingHeChuan(宁河川)

个人微信订阅号:开源FPGANingHeChuan

个体微信订阅号:开源FPGANingHeChuan

要是你想立即收到个人创作的博文推送,可以扫描左边二维码(或者长按识别二维码)关注个体微信订阅号

假如你想顿时吸纳个人写作的博文推送,能够扫描左侧二维码(或者长按识别二维码)关注个人微信订阅号

知乎ID:NingHeChuan

知乎ID:NingHeChuan

微博ID:NingHeChuan

微博ID:NingHeChuan

原稿地址:http://www.cnblogs.com/ninghechuan/p/7530878.html

原文地址:http://www.cnblogs.com/ninghechuan/p/7530878.html

相关文章