广告

原创 模拟点阵做实时剪影系统-2 将图片转为二进制信息并压缩

2019-4-12 14:54 603 3 6 分类: MCU/ 嵌入式 文集: 点阵剪影

         上一节我们将二进制01信息转化为了简单的图案,这里我们要考虑如何得到正确的01信息,也就是如何将一张图片中的人物提取出来,每一个像素用1来表示,将图片中的背景去除每一个像素用0来表示,以此实现“剪影”的01数据源。我不是专业的图像处理工程师,所以就自己琢磨着整个简单点的吧。

一、图像01

现在我们假定应用场景里背景图片都是纯色的,比如我们用纯绿色做背景色(绿色或蓝色方便抠图),那么现在需要解决的第一个问题是我们如何识别出图片中的绿色,当我们将图片中的所有绿色都识别出来,我们就可以简单地将代表绿色的像素标识为0,将其他的像素标识为1

         这里我们将图片的每一个像素都提取出来,然后分别比较RGB值,只要偏离超过20%就认为其为非绿色标记为1,其他的标记为0。下图就是将图片转为01信息的结果,左边是由01组成的文本,大概轮廓看起来像那么回事。

二、图像压缩

         接着我们需要解决的问题是,图片的像素对于点阵屏幕来说太多了点,所以我们要将像素进行压缩,本质上来说就是对图片的分辨率进行压缩,只是这里我们先将图片转为01信息,然后再对01信息进行精简。如何进行精确的图片压缩是个技术活,这里我就不花太多心思了,我使用比较粗矿的办法,每次将信息压缩至1/3的大小,比如我们有一行01信息如下,一共36个数:

000000000011111100000011111100000000

         第一步将其分为3个一组:

000 000 000 011 111 100 000 011 111 100 000 000

         将全0的精简为0、全1的精简为10多的精简为01多精简为1,得到压缩后的信息:

0 0 0 1 1 0 0 1 1 0 0 0

对于末尾可能不足3个数的情况直接抛弃,三个一组的办法避免出现01相同数量的情况,这个办法的缺点是每次都压缩至1/3。除了横向压缩,纵向也要做同样的工作,不然最后的结果会比例失调。

我们把最后生成的01信息放到上一节制作的模拟点阵显示的程序里去,可得到如下结果。

接下来需要做的就是如何从摄像头采集到实时的图片,后续如何请继续关注我的博客吧。

完整代码如下:

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Windows.Forms;

using System.IO;


namespace ImgTranslate

{

    public partial class Form1 : Form

    {

        public Form1()

        {

            InitializeComponent();

        }

        //压缩信息

        public string msgCompression(string line){

            string comLine = "";

            while (true)

            {

                //MessageBox.Show(line);

                //如果末尾出现不足3位的情况抛弃之

                if (line.Length < 3)

                {

                    break;

                }

                //MessageBox.Show(">3");

                string subLine = line.Substring(0,3);

                line = line.Substring(3,line.Length-3);

                //MessageBox.Show(subLine);

                if(subLine == "000"){

                    comLine = comLine + "0";

                    continue;

                }

                if (subLine == "001")

                {

                    comLine = comLine + "0";

                    continue;

                }

                if (subLine == "010")

                {

                    comLine = comLine + "0";

                    continue;

                }

                if (subLine == "011")

                {

                    comLine = comLine + "1";

                    continue;

                }

                if (subLine == "100")

                {

                    comLine = comLine + "0";

                    continue;

                }

                if (subLine == "101")

                {

                    comLine = comLine + "1";

                    continue;

                }

                if (subLine == "110")

                {

                    comLine = comLine + "1";

                    continue;

                }

                if (subLine == "111")

                {

                    comLine = comLine + "1";

                    continue;

                }

            }

            return comLine;

        }

        //转置

        public string[] transposition(string[] lineList) {

            string line0 = lineList[0];

            //x是行数,y是列数

            int x = lineList.Length;

            int y = line0.Length;

            char[,] numGroup = new char[x,y];

            //先转为二维数组

            for (int i = 0; i < x;i++ )

            {

                string line = lineList[i];

                char[] charArray = line.ToCharArray();

                for(int j=0; j

                    numGroup[i,j]=charArray[j];

                }

            }

            //对二维数组进行转置

            char[,] numGroup2 = new char[y, x];

            for (int i = 0; i < x; i++)

            {

                for (int j = 0; j < y; j++)

                {

                    numGroup2[j,i] = numGroup[i,j];

                }

            }

            //将二维数组转回一维

            string[] lineList2 = new string[y];

            for (int i = 0; i < y;i++ )

            {

                string line = "";

                for (int j = 0; j < x; j++ )

                {

                    line = line + numGroup2[i,j];

                }

                lineList2[i] = line;

            }

            return lineList2;

        }

       

        private void Form1_Load(object sender, EventArgs e)

        {

            //载入图片,获取宽度与高度

            Bitmap bitmap = new Bitmap("test.jpg");

            int height = bitmap.Height;

            int width = bitmap.Width;

            int sR = 1;

            int sG = 255;

            int sB = 1;

            FileStream fs = new FileStream("test.txt", FileMode.Create);

            StreamWriter sw = new StreamWriter(fs);

            string[] lineList = new string[height]; //记录01信息行的数组

            //遍历所有像素点

            for (int y = 0; y < height; y++ )

            {

                String line = "";

                for (int x = 0; x < width; x++ )

                {

                    Color color = bitmap.GetPixel(x, y);

                    //RGB任意一个颜色偏离20%就当是非绿色标记为1,否则标记为0

                    int R = color.R;

                    int G = color.G;

                    int B = color.B;

                    int rR = (sR - R) / sR;

                    int rG = (sG - G) / sG;

                    int rB = (sB - B) / sB;

                    if (rR>2||rR<=-2)

                    {

                        line = line + "1";

                        continue;

                    }

                    if (rG > 2 || rG <= -2)

                    {

                        line = line + "1";

                        continue;

                    }

                    if (rB > 2 || rB <= -2)

                    {

                        line = line + "1";

                        continue;

                    }

                    line = line + "0";

                }

                lineList[y] = line;

            }

            //信息横向压缩

            string[] lineList2 = new string[height];

            for (int i = 0; i < lineList.Length; i++)

            {

                lineList2[i] = msgCompression(lineList[i]);

            }

            //转置 将横纵倒一下

            lineList2 = transposition(lineList2);

            //信息再次压缩 确保比例一致

            string[] lineList3 = new string[lineList2.Length];

            for (int i = 0; i < lineList2.Length; i++)

            {

                lineList3[i] = msgCompression(lineList2[i]);

            }

            //转置 横纵倒回来

            lineList3 = transposition(lineList3);

            //写入文件

            for (int i = 0; i < lineList3.Length; i++)

            {

                string line = lineList3[i];

                sw.WriteLine(line);

            }

            sw.Close();

            fs.Close();

        }

    }

}


作者: 毛大闲, 来源:面包板社区

链接: https://www.mianbaoban.cn/blog/uid-me-3887969.html

版权声明:本文为博主原创,未经本人允许,禁止转载!

广告

文章评论 5条评论)

登录后参与讨论

curton 2019-4-16 21:24

好资源 学习了

CationLiu 2019-4-16 12:42

wsu_w_hotmail.com: 如何从摄像头采集到实时的图片。博主是有做成成品吗?
整好了

CationLiu 2019-4-15 12:06

wsu_w_hotmail.com: 如何从摄像头采集到实时的图片。博主是有做成成品吗?
在整

wsu_w_hotmail.com 2019-4-15 11:24

如何从摄像头采集到实时的图片。博主是有做成成品吗?

16245458_qq.com 2019-4-12 17:04

实时剪影 想法不错
相关推荐阅读
毛大闲 2019-05-29 20:06
【UFUN开箱评测】精致小巧的最佳入门板
         很久没玩开发板了,这次借着面包板社区活动也申请了一个,拿到手上第一感觉就是“小巧”。不同于以前玩过的学习板,UFUN的尺寸很小,有多...
毛大闲 2019-05-16 21:41
增加无人机控制距离的骚操作 - 4 不同网络下信息互通
         前面一节我们实现了在安卓系统中同时使用wifi和4G,现在我们要解决的问题是实现信号中转的具体功能。网络结构如下:  &n...
毛大闲 2019-05-14 13:34
【我与电子】非正经工程师的七年之痒
         有科学家做过研究,说人体细胞由于新陈代谢,每7年所有细胞都会换新一遍。也就是说,现在的你与7年前的你可能从内到外都是“全新”的。翻了...
毛大闲 2019-05-14 09:57
VLAN实验 - 1 基本设置
一、VLAN简介          VLAN(Virtual Local Area Network)的中文名为"...
毛大闲 2019-05-12 15:36
增加无人机控制距离的骚操作 - 3 在安卓上实现wifi与4G共用
         HI,大家好,休息了一段时间后终于有空来继续我们的骚操作。前面一节讲的是整体的网络结构,这里我们就要具体实现如何在安卓系统里同时访问...
毛大闲 2019-04-26 15:33
增加无人机控制距离的骚操作 - 2 指令中转的网络结构
         大家好,很久没更新了,因为要解决在手机上同时使用wifi和4G信号着实花了我一周的时间。前一节说了下大概构思,可行的办法有三种: ...
我要评论
5
3
广告
关闭 热点推荐上一条 /2 下一条