如何优化基于调色板的图像重新着色算法

时间:2015-10-06 06:24:43

标签: python django algorithm image-processing

我是一个场景,我在其中生成针对特定图像的调色板。然后我想点击任何调色板颜色n并选择一个新颜色放在具有前一颜色代码的所有像素上。我已经完成了,并且它正在工作,但我需要您帮助优化其结果和时间。使用颜色小偷生成调色板的代码是:

function make_pallete(){
    var images = document.getElementById('default_img');
    colors = colorThief.getPalette(images, 8);
    for (var i = 0 ; i < colors.length; i++) {
        $('#swatches').append("<div class='swatch' style='background-color:rgb("+       colors[i][0]+ ","+ colors[i][1] + "," + colors[i][2] +")'></div>");
    }
}

我正在进行重新着色的Django视图是:

def recolor_image(request):
    if request.method == "POST":
        pic = request.POST.get("image")
        old_rgb = request.POST.getlist("old_rgb[]")
        new_rgb = request.POST.getlist("new_rgb[]")
        path = "D:/pysofts/flagcarpets" + pic
        pic  = path
        picture = Image.open(pic)
        # Get the size of the image
        width,height = picture.size
        print old_rgb
        for x in range(0, width):
            for y in  range(0, height):
                current_color = picture.getpixel((x,y))
                r,g,b = current_color
                if r in range(int(old_rgb[0]) - 50, int(old_rgb[0]) + 50) and g in     range(int(old_rgb[1]) - 50, int(old_rgb[1]) + 50) and b in range(int(old_rgb[2]) - 50, int(old_rgb[2]) + 50):
                    r = int(new_rgb[0])
                    g = int(new_rgb[1])
                    b = int(new_rgb[2])
               new_color = (r,g,b)
               picture.putpixel((x,y), new_color)
        picture.save(path)
        return HttpResponse(pic)

正如我所说,它重新着色图像,但效率很差(它没有为每个前一个像素添加新颜色)n重新着色图像大约需要30秒。什么是更精确的算法?

1 个答案:

答案 0 :(得分:2)

什么是图像分辨率和颜色?

基于像素的重新着色图像在1024x768左右应该只需要几个[ms] 如果您的色彩数量低至256,则可以使用基于调色板的图像(如GIF,BMP,PCX)来仅更改调色板而不是像素以改变速度。
如果你想要真正的速度,请使用C / C ++

问题:

我看到的第一件事是 GDI getpixel访问权限,即 SLOW 。 (见bitmap ScanLine property)。因此,创建指向图像行的指针数组并使用它(每行只调用一次ScanLine然后使用数组)这将避免GDI检查减速。

每个getpixel / ScanLine调用调用大约100个子调用来检查类型,格式,分辨率等 如果您访问自己的指针数组,那么您只需访问内存而不会有任何额外的减速(通常比getpixel快约1000倍)。 在您的平台中找到ScanLine[]等效项并重写。以下是VCL/C++中的示例,以便您了解要查找的内容以及如何使用它 它应该与GDI接口几乎相同。

如果您想使用索引颜色(调色板)

您可以使用OpenGL和索引颜色进行可视化。通过这种方式,您只需更改调色板,并且opengl可以自行重新调整其余部分 这个过程在编辑时有利于速度,它只在保存时重新着色。

另一种选择是使用256色调色板图像文件格式(GIF,BMP,PCX) 为此,您必须将颜色限制为256 您可以使用任何方法。这是我的:Effective gif/image color quantization,但这会改变颜色动态范围,看那里的图像。

<强>重着色

如果您对调色板进行了排序,则可以使用二分搜索来加快处理速度 颜色太多,最好使用词典 例如,创建列表:List<DWORD> r0[256],g0[256],b0[256];。每个颜色都包含以rgb值开头的所有颜色 例如,r0[55]将使用red=55保留所有使用的颜色 这样,您可以在O(n^2)而不是O(n^3)中搜索不计算二进制搜索 请参阅上面的GIF链接,了解我如何重新着色以获得更多创意。