C# + DeOldify 实现黑白照片上色

前言

给大家介绍一个关于给黑白照片上色的软件DeOldify,是基于AI深度学习技术开发的开源软件,功能强大,大小仅123MB,免安装便携版。

Github:https://github.com/jantic/DeOldify

效果

多萝西娅·兰格的《移民母亲》(1936)

c172c77f48b6e3d5db4a4d43ea7c1bf0.jpeg

马里兰州Glen Echo Careta女士吉普赛营地(1925年)

87e57983b02c79d2bba1499b8e702f94.jpeg

ccb279d16dbef39a03a76f8d3086af9c.png
32fdf075672d60c54b9adf889c5a0b16.png

项目

工具:VS2022

环境:.NET Framework 4.8/OpenCvSharp 4.8

94c2b70db4c2f63f5685334f725293c1.png

代码

3cc5179a51d506697e4d29fc2603a506.png

027f39173d5134deaa9f6e18c8e6694b.png

d2a0203db2fce97ec9032ebbab5b05a4.png

for (int y = 0; y < result.Height; ++y)  
            {  
                for (int x = 0; x < result.Width; ++x)  
                {  
                    var c = result.GetPixel(x, y);  
                    var l = (byte)((c.R + c.G + c.B) / 3);  
                    result.SetPixel(x, y, Color.FromArgb(c.A, l, l, l));  
                }  
            }  
            return result;  
        }  
   
        /// <summary>  
        /// Blurrifies the image.  
        /// </summary>  
        /// <param name="source">Input image.</param>  
        /// <returns>Blurrified image.</returns>  
        private static Bitmap __Blurify(Bitmap source)  
        {  
            var output = new Bitmap(source.Width, source.Height);  
            for (int y = 0; y < output.Height; ++y)  
            {  
                for (int x = 0; x < output.Width; ++x)  
                {  
                    var a = 0f;  
                    var r = 0f;  
                    var g = 0f;  
                    var b = 0f;  
                    for (int ky = 0; ky < 5; ++ky)  
                    {  
                        var iy = y + ky - 2;  
                        if ((iy < 0) || (iy >= source.Height))  
                        {  
                            continue;  
                        }  
                        for (int kx = 0; kx < 5; ++kx)  
                        {  
                            var ix = x + kx - 2;  
                            if ((ix < 0) || (ix >= source.Width))  
                            {  
                                continue;  
                            }  
                            var c = source.GetPixel(ix, iy);  
                            a += c.A;  
                            r += c.R;  
                            g += c.G;  
                            b += c.B;  
                        }  
                    }  
                    output.SetPixel(x, y, Color.FromArgb((byte)(a / 25), (byte)(r / 25), (byte)(g / 25), (byte)(b / 25)));  
                }  
            }  
            return output;  
        }  
   
        private void button2_Click(object sender, EventArgs e)  
        {  
            if (pictureBox1.Image == null)  
            {  
                textBox1.Text = "请先选择图片";  
                return;  
            }  
   
            button2.Enabled = false;  
            pictureBox2.Image = null;  
            textBox1.Text = "";  
   
           Task task = new Task(() =>  
            {  
   
                dt1 = DateTime.Now;  
   
                System.Threading.Thread.Sleep(2000);  
   
                __Output = DeOldify.Colorize(__Input);  
   
                //if (__Output.Height > __Output.Width)  
                //{  
                //    __NormalOutput = new Bitmap(__Output, (int)(256f / __Output.Height * __Output.Width), 256);  
                //}  
                //else  
                //{  
                //    __NormalOutput = new Bitmap(__Output, 256, (int)(256f / __Output.Width * __Output.Height));  
                //}  
   
                //__BlurryOutput = __Blurify(__NormalOutput);  
   
                //__Output = __NormalOutput;  
   
                pictureBox2.Image = __Output;  
   
                dt2 = DateTime.Now;  
   
                textBox1.Invoke(new Action(() =>  
                {  
                    TimeSpan ts = dt2.Subtract(dt1);  
                    textBox1.Text = "耗时:" + ts.TotalSeconds + "s";  
                }));  
   
                button2.Invoke(new Action(() =>  
                {  
                    button2.Enabled = true;  
                }));  
   
   
                //GC.Collect();  
   
            });  
   
            task.Start();  
        }  
   
        private void Form1_Load(object sender, EventArgs e)  
        {  
            startupPath = System.Windows.Forms.Application.StartupPath;  
            model = "Artistic.hmodel";  
   
            //Artistic model with half-precision floating point weights. Less accurate than original float32 model, but requires 2 times less disk space.  
            //Artistic.hmodel  
   
            //Artistic model with single-precision floating point weights. More accurate than compressed float16 model.  
            //Artistic.model  
   
            //Stable model with single-precision floating point weights. Less accurate than original float32 model, but requires 2 times less disk space.  
            //Stable.hmodel  
   
            //Stable model with single-precision floating point weights. More accurate than compressed float16 model.  
            //Stable.model";  
            try  
            {  
                DeOldify.Initialize(model);  
                textBox1.Text = "模型["+ model + "]初始化成功";  
                DeOldify.Progress += (float Percent) =>  
                {  
                    textBox1.Invoke(new Action(() =>  
                    {  
                        textBox1.Text = string.Format("完成进度:{0}%,请稍等……", Percent.ToString("f2"));  
                    }));  
                };  
            }  
            catch (Exception ex)  
            {  
                textBox1.Text = "模型初始化失败,异常信息:" + ex.Message;  
            }  
        }  
        private void button3_Click(object sender, EventArgs e)  
        {  
            if (pictureBox2.Image == null)  
            {  
                return;  
            }  
            var SFD = new SaveFileDialog();  
            SFD.Title = "保存";  
            SFD.Filter = "Images (*.bmp)|*.bmp|Images (*.emf)|*.emf|Images (*.exif)|*.exif|Images (*.gif)|*.gif|Images (*.ico)|*.ico|Images (*.jpg)|*.jpg|Images (*.png)|*.png|Images (*.tiff)|*.tiff|Images (*.wmf)|*.wmf";  
            if (SFD.ShowDialog() == DialogResult.OK)  
            {  
                switch (SFD.FilterIndex)  
                {  
                    case 1:  
                        {  
                            __Output.Save(SFD.FileName, ImageFormat.Bmp);  
                            break;  
                        }  
                    case 2:  
                        {  
                            __Output.Save(SFD.FileName, ImageFormat.Emf);  
                            break;  
                        }  
                    case 3:  
                        {  
                            __Output.Save(SFD.FileName, ImageFormat.Exif);  
                            break;  
                        }  
                    case 4:  
                        {  
                            __Output.Save(SFD.FileName, ImageFormat.Gif);  
                            break;  
                        }  
                    case 5:  
                        {  
                            __Output.Save(SFD.FileName, ImageFormat.Icon);  
                            break;  
                        }  
                    case 6:  
                        {  
                            __Output.Save(SFD.FileName, ImageFormat.Jpeg);  
                            break;  
                        }  
                    case 7:  
                        {  
                            __Output.Save(SFD.FileName, ImageFormat.Png);  
                            break;  
                        }  
                    case 8:  
                        {  
                            __Output.Save(SFD.FileName, ImageFormat.Tiff);  
                            break;  
                        }  
                    case 9:  
                        {  
                            __Output.Save(SFD.FileName, ImageFormat.Wmf);  
                            break;  
                        }  
                }  
                MessageBox.Show("保存成功,位置:"+SFD.FileName);  
            }  
        }  
    }  
}

总结

软件的使用也非常简单,鼠标移动至左侧图片点击打开图片,然后点击下方的 DeOldify 按钮即可开始处理,处理完成后,鼠标移动至右侧图片会显示 Save 按钮,点击保存即可,处理速度由电脑配置决定,配置越高处理越快。

目前项目已经维护了几年时间,是一款相当成熟的软件了,DeOldify 采用了 NoGAN 这样一种新型的、高效的图像到图像的 GAN 训练方法。细节处理效果更好,渲染也更逼真。至于能不能达到各位的要求,这就仁者见仁智者见智了。

转自:天天代码码天天

链接:mp.weixin.qq.com/s/0XYK5jEixlFzdgfj0PDwPA

- EOF -

技术群:添加小编微信dotnet999

公众号:dotnet讲堂

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值