如何将拆分图像显示为 8x8 像素?
How to show a split images into 8x8 pixels?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Emgu.CV;
using Emgu.CV.Util;
using Emgu.CV.Structure;
namespace DCTTransform
{
public partial class Form1 : Form
{
Image<Bgr, Byte> img;
Image<Ycc, Byte> imgYcc;
Bitmap bmp;
public Form1()
{
InitializeComponent();
}
private void btBrowse_Click(object sender, EventArgs e)
{
OpenFileDialog od = new OpenFileDialog();
if (od.ShowDialog() == DialogResult.OK)
{
img = new Image<Bgr, byte>(od.FileName);
pcCitra.Image = img.ToBitmap();
label1.Text = img.Width.ToString();
}
}
//Split citra
public List<Image> subBlok(Image img, int blokX, int blokY)
{
List<Image> res = new List<Image>();
int pembagiLebar = img.Width / blokX;
int pembagiTinggi = img.Height / blokY;
for (int i = 0; i < blokX; i++)//baris
{
for (int j = 0; j < blokY; j++)//kolom
{
Bitmap bmp = new Bitmap(img.Width / pembagiLebar, img.Height / pembagiTinggi);
//Bitmap bmp = new Bitmap(img.Width, img.Height);
Graphics grp = Graphics.FromImage(bmp);
grp.DrawImage(img, new Rectangle(0,0 , bmp.Width, bmp.Height), new Rectangle(j * bmp.Width, i * bmp.Height, bmp.Width, bmp.Height), GraphicsUnit.Pixel);
res.Add(bmp);
}
}
return res;
}
private void btTransform_Click(object sender, EventArgs e)
{
//SplitImage
List<Image> imgs = subBlok(pcCitra.Image, 8, 8);
pbDCT.Image = imgs[0];
}
}
}
我用这段代码将图像分成 8 x 8 像素,但结果只在左上角显示 1 个块 (8 x 8)。
我想要的是这样的:
|xxxx|xxxx|xxxx|xxxx|..........
直到与原始图像宽度相同。
你能帮我解决这个问题吗?
如果您想将源图像分成多个 8x8 块,那么您的变换函数的循环是不正确的。如果您想将源图像分成 64 个图块,那么它们是正确的,但 DCT 通常不适用于 64 个静态图像集。我不清楚你想要哪一张,但我在这里为多张 8x8 图片修复了它:
List<Image> res = new List<Image>();
int pembagiLebar = (int)Math.Ceil((float)img.Width / (float)blokX);
int pembagiTinggi = (int)Math.Ceil((float)img.Height / (float)blokY);
for (int i = 0; i < pembagiLebar ; i++)//baris
{
for (int j = 0; j < pembagiTinggi ; j++)//kolom
{
Bitmap bmp = new Bitmap(blokX, blokY);
using (Graphics grp = Graphics.FromImage(bmp)) {
grp.DrawImage(img, 0, 0, new Rectangle(i * blokX, j * blokY, blokX, blokY), GraphicsUnit.Pixel);
}
res.Add(bmp);
}
}
return res;
右侧和底部边缘的边界条件也很烦人(我这里没有),因为源图像尺寸可能不是 8 的倍数。
您可以采用多种方法。最简单的处理方法是将图像值存储在长度为 8 的倍数的行中。填充数据。对行数做同样的事情然后对行数做同样的事情。
然后块是(假设灰度)
X = starting point
v0 = X
v1 = X + 1
v2 = X + 2
. . .
v8 = X + row length
v9 = X + row length + 1
v10 = X + row length + 2
. . .
v63 = x = 7 * row length + 7
To move to the next block in the row X = X + 8. When you reach the end of the row
X = X + 8 * row length
请记住,您的输出元素需要是输入元素大小的两倍。如果你的图像数据是 8 位,你的 DCT 输出将需要是 16 位的整数表示(或浮点值)。
如果您无法填充数据,最好的办法是将值复制到 64 条目数组。你会做一个类似于上面的循环,但是,任何时候你需要访问一个超出图像宽度或高度的值,插入一个 0 到临时数组中。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Emgu.CV;
using Emgu.CV.Util;
using Emgu.CV.Structure;
namespace DCTTransform
{
public partial class Form1 : Form
{
Image<Bgr, Byte> img;
Image<Ycc, Byte> imgYcc;
Bitmap bmp;
public Form1()
{
InitializeComponent();
}
private void btBrowse_Click(object sender, EventArgs e)
{
OpenFileDialog od = new OpenFileDialog();
if (od.ShowDialog() == DialogResult.OK)
{
img = new Image<Bgr, byte>(od.FileName);
pcCitra.Image = img.ToBitmap();
label1.Text = img.Width.ToString();
}
}
//Split citra
public List<Image> subBlok(Image img, int blokX, int blokY)
{
List<Image> res = new List<Image>();
int pembagiLebar = img.Width / blokX;
int pembagiTinggi = img.Height / blokY;
for (int i = 0; i < blokX; i++)//baris
{
for (int j = 0; j < blokY; j++)//kolom
{
Bitmap bmp = new Bitmap(img.Width / pembagiLebar, img.Height / pembagiTinggi);
//Bitmap bmp = new Bitmap(img.Width, img.Height);
Graphics grp = Graphics.FromImage(bmp);
grp.DrawImage(img, new Rectangle(0,0 , bmp.Width, bmp.Height), new Rectangle(j * bmp.Width, i * bmp.Height, bmp.Width, bmp.Height), GraphicsUnit.Pixel);
res.Add(bmp);
}
}
return res;
}
private void btTransform_Click(object sender, EventArgs e)
{
//SplitImage
List<Image> imgs = subBlok(pcCitra.Image, 8, 8);
pbDCT.Image = imgs[0];
}
}
}
我用这段代码将图像分成 8 x 8 像素,但结果只在左上角显示 1 个块 (8 x 8)。
我想要的是这样的:
|xxxx|xxxx|xxxx|xxxx|..........
直到与原始图像宽度相同。
你能帮我解决这个问题吗?
如果您想将源图像分成多个 8x8 块,那么您的变换函数的循环是不正确的。如果您想将源图像分成 64 个图块,那么它们是正确的,但 DCT 通常不适用于 64 个静态图像集。我不清楚你想要哪一张,但我在这里为多张 8x8 图片修复了它:
List<Image> res = new List<Image>();
int pembagiLebar = (int)Math.Ceil((float)img.Width / (float)blokX);
int pembagiTinggi = (int)Math.Ceil((float)img.Height / (float)blokY);
for (int i = 0; i < pembagiLebar ; i++)//baris
{
for (int j = 0; j < pembagiTinggi ; j++)//kolom
{
Bitmap bmp = new Bitmap(blokX, blokY);
using (Graphics grp = Graphics.FromImage(bmp)) {
grp.DrawImage(img, 0, 0, new Rectangle(i * blokX, j * blokY, blokX, blokY), GraphicsUnit.Pixel);
}
res.Add(bmp);
}
}
return res;
右侧和底部边缘的边界条件也很烦人(我这里没有),因为源图像尺寸可能不是 8 的倍数。
您可以采用多种方法。最简单的处理方法是将图像值存储在长度为 8 的倍数的行中。填充数据。对行数做同样的事情然后对行数做同样的事情。
然后块是(假设灰度)
X = starting point
v0 = X
v1 = X + 1
v2 = X + 2
. . .
v8 = X + row length
v9 = X + row length + 1
v10 = X + row length + 2
. . .
v63 = x = 7 * row length + 7
To move to the next block in the row X = X + 8. When you reach the end of the row
X = X + 8 * row length
请记住,您的输出元素需要是输入元素大小的两倍。如果你的图像数据是 8 位,你的 DCT 输出将需要是 16 位的整数表示(或浮点值)。
如果您无法填充数据,最好的办法是将值复制到 64 条目数组。你会做一个类似于上面的循环,但是,任何时候你需要访问一个超出图像宽度或高度的值,插入一个 0 到临时数组中。