所以我基本上尝试在java中使用四叉树实现基本的图像压缩算法;但是,我真的坚持如何将超过四个像素的任何东西变成四叉树。我的直觉是递归。
现在基本上,这是我的想法。这显然仅适用于具有4个像素的图像。我不应该如何深入挖掘图像阵列。
if(sideLength == 2){
QuadNode parent = new QuadNode(image.length);
for(int i = 0; i < image.length; i++){
for(int j = 0; j < image[0].length; j++){
QuadNode child = new QuadNode(image[i][j], image.length/2);
if (j == 0 && i == 0)
parent.setQuadrant(UpperLeft, child);
if (j == 0 && i == 1)
parent.setQuadrant(LowerLeft, child);
if (j == 1 && i == 0)
parent.setQuadrant(UpperRight, child);
if (j == 1 && i == 1)
parent.setQuadrant(LowerRight, child);
}
}
return new QuadTree(parent);
}
答案 0 :(得分:3)
压缩图像的方法有很多种。以下是使用四叉树的算法。
当您递归地划分图像时,想法是最小化树中使用的四叉树节点的数量。如果该矩形中的所有像素都包含相同的颜色,我们就会停止划分特定节点。
示例Node结构如下所示。
class QuadTreeNode
{
Point topLeft;
int width;
int height;
QuadTreeNode children[4];
int color;
};
如果您将图像分割为中心,则无法实现最佳压缩。
现在的主要任务是找出(i,j)我们应该分开的地方。对于这种动态编程和散列很方便。
class HashValue
{
Point p; // location to cut into quads
int count;// To contain number of Quadtree Nodes;
};
HashMap<Rect,HashValue> H;
int createQuadTree(Rect rect)
{
if(Hash.find(rect)!= Hash.end()) return Hash[rect];
if(isMonoChromatic(rect))// If all the pixels are of same color we stop dividing.
{
Hash[rect] = {NULL,1};
return 1;
}
int x=rect.x,y=rect.y,w =rect.w,h=rect.h;
int minCount;
Point minCut;
for(i=x;i<x+w;i++)
{
for(j=y;j<x+h;j++)
{
int val = 1;
val= val+ createQuadTree(Rect(x,y,i,j));
val= val+ createQuadTree(Rect(x,j,w-i,j));
val= val+ createQuadTree(Rect(i,y,i,h-j));
val= val+ createQuadTree(Rect(i,j,w-i,h-j));
if(val < minCount)
{
minCount = val;
minCutPoint = {i,j};
}
}
}
Hash[rect] = {minCutPoint,minCount};
return val;
}
使用这个HashTable可以直接构建QuadTree。它是复杂的算法,具有O(M,N)递归步骤,每个步骤O(M,N)加到O(M ^ 2,N ^ 2)。您可以通过对图像进行一些预处理来降低isMonoChromatic函数的复杂性。
P.S。对不起,很长的帖子。我希望它有所帮助。