使用最近邻居扩展图像 [英] Scaling up an image using nearest-neighbor

查看:144
本文介绍了使用最近邻居扩展图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直试图让我的程序扩大图像。我在为缩放图像分配新空间时遇到了一些问题,但我认为它是固定的。我遇到的问题是当我试图从我的临时内存持有者发回我的图像时程序崩溃。

I have been trying to make my program scale up an image. I had some problem to allocate new space for my scaled image, but I think it is fixed. The problem I am having is that the program crashes when I am trying to send back my image from my temporary memory holder.

加载的图像放在我的 struct 图像 。像素位于
img->像素中,高度在 img-> height 中宽度 img-> width 。但是当我将像素从我的 tmp2 struct 转移到我的<$ c $时,我不知道为什么程序会崩溃c> img struct 虽然当我做相反的事情时它没有崩溃。以下是代码:

The loaded image is placed in my struct Image. The pixels are placed in img->pixels, the height in img->height and the width in img->width. But I have no idea why the program crashes when I transfer the pixels from my tmp2 struct to my img struct while it does not crash when I do the opposite. Here is the code:

void makeBigger(Image *img, int scale) {

    Image *tmp2;
    tmp2 = (Image*)malloc(sizeof(Image));
    tmp2->height = img->height*scale;
    tmp2->width = img->width*scale;

    tmp2->pixels = (Pixel**)malloc(sizeof(Pixel*)*tmp2->height);
    for (unsigned int i = 0; i < img->height; i++)
    {
        tmp2->pixels[i] = (Pixel*)malloc(sizeof(Pixel)*tmp2->width);
        for (unsigned int j = 0; j < img->width; j++)
        {
            tmp2->pixels[i][j] = img->pixels[i][j];
        }
    }
    free(img->pixels);

    //scaling up the struct's height and width
    img->height *= scale;
    img->width *= scale;

    img->pixels = (Pixel**)malloc(sizeof(Pixel*)*img->height);
    for (unsigned int i = 0; i < tmp2->height; i++)
    {
        img->pixels[i] = (Pixel*)malloc(sizeof(Pixel)*img->width);
        for (unsigned int j = 0; j < tmp2->width; j++)
        {
            img->pixels[i][j] = tmp2->pixels[i+i/2][j+j/2];
        }
    }
}

如果你我会很高兴的知道如何使最近邻方法工作。谢谢!

I would be glad if you have any idea of how to make the nearest-neighbor method to work. Thank you!

编辑:我正在尝试裁剪内部矩形,以便我可以将其缩放(缩放)。

I am trying to crop the inner rectangle so I can scale it up (zoom).

Image *tmp = (Image*)malloc(sizeof(Image));
tmp->height = img->height / 2;
tmp->width = img->width / 2;

tmp->pixels = (Pixel**)malloc(sizeof(Pixel*) * tmp->height);
for (unsigned i = img->height / 4 - 1; i < img->height - img->height / 4; i++) {
    tmp->pixels[i] = (Pixel*)malloc(sizeof(Pixel) * tmp->width);
    for (unsigned j = img->width / 4; j < img->width - img->width / 4; j++) {
        tmp->pixels[i][j] = img->pixels[i][j];
    }
}

for (unsigned i = 0; i < img->height; i++) {
    free(img->pixels[i]);
}
free(img->pixels);

img->height = tmp->height;
img->width = tmp->width;
img->pixels = tmp->pixels;
free(tmp);


推荐答案

我看到你过于复杂的事情(走过去)图像两次例如)。
这是代码(我发布整个程序 - 我假设 Pixel 图像可能与你的不一样),但是如果你复制/粘贴 makeBigger 它应该在你的代码 OOTB 中工作:

I see that you're overcomplicating things (walking over the image twice for example).
Here's the code (I am posting the whole program - I made assumptions about Pixel and Image that might not match what you have), but if you copy/paste makeBigger it should work in your code OOTB:

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

typedef uint32_t Pixel;

typedef struct {
    uint32_t width, height;
    Pixel **pixels;
} Image;


void makeBigger(Image *img, int scale) {
    uint32_t i = 0, j = 0;
    Image *tmp = (Image*)malloc(sizeof(Image));
    tmp->height = img->height * scale;
    tmp->width = img->width * scale;

    tmp->pixels = (Pixel**)malloc(sizeof(Pixel*) * tmp->height);
    for (i = 0; i < tmp->height; i++) {
        tmp->pixels[i] = (Pixel*)malloc(sizeof(Pixel) * tmp->width);
        for (j = 0; j < tmp->width; j++) {
            tmp->pixels[i][j] = img->pixels[i / scale][j / scale];
        }
    }

    for (i = 0; i < img->height; i++)
        free(img->pixels[i]);
    free(img->pixels);

    img->width = tmp->width;
    img->height = tmp->height;
    img->pixels = tmp->pixels;
    free(tmp);
}


void printImage(Image *img) {
    printf("Width: %d, Height: %d\n", img->width, img->height);
    for (uint32_t i = 0; i < img->height; i++) {
        for (uint32_t j = 0; j < img->width; j++)
            printf("%3d", img->pixels[i][j]);
        printf("\n");
    }
    printf("\n");
}


int main() {
    uint32_t i = 0, j = 0, k = 1;
    Image img;
    // Allocate and initialize the image data
    img.height = 2;
    img.width = 3;
    img.pixels = (Pixel**)malloc(sizeof(Pixel*) * img.height);
    for (i = 0; i < img.height; i++) {
        img.pixels[i] = (Pixel*)malloc(sizeof(Pixel) * img.width);
        for (j = 0; j < img.width; j++)
            img.pixels[i][j] = k++;
    }

    printImage(&img);
    makeBigger(&img, 2);
    printImage(&img);

    // Deallocate the image data
    for (i = 0; i < img.height; i++)
        free(img.pixels[i]);
    free(img.pixels);

    return 0;
}

注释 makeBigger 相关 - 旨在替换作为参数给出的图像内容:

Notes (makeBigger related - designed to replace the content of the image given as argument):


  • 构建一个临时图像是放大的

  • 仅遍历临时图像一次(在我们分配像素时填充其像素);要保持缩放到原始图像并确保将相应的像素复制到新图像中,只需将索引除以缩放因子: tmp-> pixels [i] [j] = img-> pixels [i / scale] [j / scale]

  • 取消分配原始图片内容:因为每个像素行是 malloc ed,它也应该是免费 d(免费(img->像素) ); 单独会产生内存泄漏

  • 将临时图像内容保存到原始内容中然后取消分配

  • Construct a temporary image that will be the enlarged one
  • Only traverse the temporary image once (populate its pixels as we allocate them); to maintain scaling to the original image and make sure that the appropriate pixel is "copied" into the new one, simply divide the indexes by the scaling factor: tmp->pixels[i][j] = img->pixels[i / scale][j / scale]
  • Deallocate the original image content: since each pixel row is malloced, it should also be freed (free(img->pixels); alone will yield memory leaks)
  • Save the temporary image content into the original and then deallocate it

运行上述程序(使用 gcc 编译)将输出以下内容:

Running the above program (compiled using gcc), will output the following:


宽度:3,高度:2
1 2 3
4 5 6

宽度:6,身高:4
1 1 2 2 3 3
1 1 2 2 3 3
4 4 5 5 6 6
4 4 5 5 6 6

这篇关于使用最近邻居扩展图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆