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

2019-4-12 14:54 3210 25 7 分类: 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;

                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 = 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 = msgCompression(lineList);

            }

            //转置 将横纵倒一下

            lineList2 = transposition(lineList2);

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

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

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

            {

                lineList3 = msgCompression(lineList2);

            }

            //转置 横纵倒回来

            lineList3 = transposition(lineList3);

            //写入文件

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

            {

                string line = lineList3;

                sw.WriteLine(line);

            }

            sw.Close();

            fs.Close();

        }

    }

}


作者: 布兰姥爷, 来源:面包板社区

链接: https://mbb.eet-china.com/blog/uid-me-3887969.html

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

PARTNER CONTENT

文章评论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

实时剪影 想法不错
相关推荐阅读
布兰姥爷 2023-04-21 23:07
跟姥爷深度学习4 从数学计算看神经网络
一、前言我们前面简单的做了一个气温预测,经过反复调试,效果还不错。实际上在这个方向上我们还可以更进一步优化,但因为我们是学习嘛,主要还是看广度而不是深度。考虑到后面要开始学习卷积网络,我们必须把更基础...
布兰姥爷 2023-04-21 23:04
跟姥爷深度学习3 神经网络的调试实操
一、前言前面我们做了一次天气预测的模型,训练的结果都还好,网络好歹是“拟合”了,但预测数据不合预期让我一直耿耿于怀。所以我又花了很长时间来研究为什么,我的理论依据明明没有问题(今日平均温度与近一周平均...
布兰姥爷 2023-04-21 23:02
跟姥爷深度学习2 TensorFlow的基本用法
一、前言前面我们浅用TensorFlow做了个天气预测,虽然效果不咋样,但算是将整个流程跑通了。这一篇我们在之前基础上对TensorFlow的一些参数进行简单介绍,在接口文件的基础上了解各参数的简单含...
布兰姥爷 2023-04-11 22:22
跟姥爷深度学习1,浅用tensorflow做个天气预测
一、前言最近人工智能、深度学习又火了,我感觉还是有必要研究一下。三年前浅学了一下原理没深入研究框架,三年后感觉各种框架都成熟了,现成的教程也丰富了,所以我继续边学边写。原教程链接:https://ww...
布兰姥爷 2023-03-29 12:41
AI为啥要用显卡
一、前言GPT的发布让AI再次热了起来,与上次阿尔法狗不同的是,现在人人都可以跟聊上几句,给它出出难题,还能调戏下。同期英伟达发布了针对AI领域的全新GPU H100,有的童鞋会疑惑,这个英伟达不是做...
布兰姥爷 2019-11-04 21:09
【零基础】使用Tensorflow实现神经网络
一、序言  前面已经逐步从单神经元慢慢“爬”到了神经网络并把常见的优化都逐个解析了,再往前走就是一些实际应用问题,所以在开始实际应用之前还得把“框架”翻出来,因为后面要做的工作需要我们将精力集中在业务...
EE直播间
更多
我要评论
5
25
关闭 站长推荐上一条 /3 下一条