Use Go to achieve the automatic adjustment of picture size

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

When I first went to college, in the last few minutes of class, I skipped class and ran to another class I barely knew. It happened that the class was one of the best lessons I ever felt-computer vision. In addition, the class introduced a great algorithm: Seam carving, finely crafted.

This algorithm is probably Jiangzi: in general we want to change the size of the picture, we will use the way of cropping and zooming, so that the picture will lose a lot of important information, in the process of processing, the picture is even distorted. So, how can we find the least part of the visual information in the picture, to adjust the size of the picture, just remove this part is not it possible?

Show us a beautiful picture: The Open Blue sky, the Junyi Castle. But, for us, the picture is a bit big, we have to go to a minor. How do you do that?

Coraaller
Translated 3 weeks ago

2 Person top

top translation of good Oh!

The first idea to get into our brains is to change the size of the original image. The image after the change (e.g.) becomes smaller, and all the main information (the person on the left, the castle on the right) is still on the new image. However, the changed image has a problem, the right castle is deformed, so the image after the change is not perfect. In most cases, this change in the image is acceptable, but if we try to provide a high-quality image, the change is unacceptable.

Another idea is to cut off part of the original image to fit our new size (e.g.). Basically we can understand that the new image has a fatal disadvantage, half the castle is cut off, and the person on the left is now too close to the edge of the image. Compared to the original image, the new image does contain most of the original image information, but also lost a lot of important information. I personally like the Baolou on the right side of the castle, hoping to keep this baolou in the new image. Fortunately, we can do this.

Let's look at the image above, the size of the image has been reduced, in the new image, the castle is complete, and the left person is no longer located on the edge of the image. The new image above is processed by an algorithm called seam carving. The algorithm dynamically monitors the original image, discovers less important parts of the original image, and cuts out the less important images. In the new image above, you can see that the algorithm removes the blue sky from the right side of the castle and removes the blue sky, which is partially located in the middle part of the original image.

Hailincai
Translated 3 weeks ago

0 Person Top

top translation of good Oh!

Other translation versions (1)
Loading ...

How does it determine which areas should be removed first? We find the answer by studying an algorithm implemented by the go language. We examine each step of the algorithm and the effect of each step on the image below. Although this algorithm is used to reduce the height of the image, it can be easily modified to reduce the width of the image.

The algorithm consists of three main steps: generating an energy map from the original, locating "seam" to find the lowest energy consumption, and removing the found seam from the image.

Reduceheight uses the seam carving algorithm to reduce the height of a given image with N pixels. Func reduceheight (im image. image, n int) image. Image {energy: = Generateenergymap (IM) Seam: = Generateseam (energy) return removeseam (IM, Seam)}

The energy graph calculates how much "energy" a point in the image contains, that is, how much information the point contains. The low-energy pixels are fused with the surrounding pixels, and the effect of removing them on the entire graph is less. Therefore, the calculation of the energy graph is carried out with the method of considering the horizontal and vertical gradient values of the image. The energy graph produced by this method, where each point represents the degree to which the corresponding point in the original image is similar or different from the surrounding point.
Fortunately, this can be done by a specific filter (which uses a Sobel filter) to calculate the convolution of the input image. I don't discuss convolution in detail here, but one important thing to know is that by applying the Sobel filter to a grayscale image of an input image (usually an optional smoothing filter, such as a Gaussian filter, to get a grayscale image), we can easily get the gradient of the input image. To do this I use a powerful gift library.

Generateenergymap applies input grayscale and Sobel filters to the input image to generate the energy graph. Func Generateenergymap (im image. Image) image. Image {g: = gift. New (gift. Grayscale (), gift. Sobel ()) Res: = image. Newrgba (im. Bounds ()) G.draw (res, IM) return res}

Hxapp2
Translated 3 weeks ago

0 Person Top

top translation of good Oh!

As expected, high-energy areas are generally marginal, and low-energy areas are expanded by a small number of similar colors (skies). From here we can estimate that the reduction of the height of the picture, the reduced portion should be mostly in the sky area, the other parts remain unchanged.

The next step is to decide which pixels need to be removed. We will reduce the height of a pixel by one pixel, and we need a column of a column to find that pixel to remove. We want to find a range of pixel sets with the lowest total energy possible, removing these seam and minimizing the effect on the entire image. You can determine the best point to remove pixels in the following two steps:

Generateseam returns the optimal level Seam.func generateseam (IM image) that can be eliminated. Image) Seam {mat: = Generatecostmatrix (IM) return Findlowestcostseam (MAT)}

The first step is to use an eight-connected area pixel to filter the entire image horizontally to obtain a depletion matrix containing the lowest accumulated energy of "seams".

This time we first look at the following code:

 GenerateCostMatrix  from the left end of the image to each pixel, create an indication of the minimum consumption seam matrix .//// mat[x][y]  is the accumulated energy of seam from the left end of the image to the Y-pixel point of the column X row. Func generatecostmatrix (im image. Image)  [][]float64 {    min, max := im. Bounds (). Min, im. Bounds (). Max    height, width := max. Y-min.y, max. X-min.x    mat := make ([][]float64, width)     for  X := min. X; x < max. X; x++ {        mat[x-min. X] = make ([]float64, height)     }    // initialize  first column of matrix    for y := min. Y; y < max. Y; y++ {        e, _, _, a := im. at (0, y). RGBA ()         mat[0][Y-min. Y] = float64 (e)  / float64 (a)     }    updatepoint  := func (X, y int)  {        e, _, _ ,  a := im. at (x, y). RGBA ()         up, down := math. Maxfloat64, math. maxfloat64        left := mat[x-1][y]         if y != min. Y&NBSP;{&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;UP&NBSP;=&NBSP;MAT[X-1][Y-1]         }        if y  < max. y-1 {            down = mat[x-1][y+ 1]        }        val :=  math. MIn (Float64 (left),  math. Min (Float64 (UP),  float64 (Down)))         mat[x][y] = val  +  (Float64 (e)  / float64 (a))     }    //  calculate the remaining columns iteratively    for x :=  min. X + 1; x < max. X; x++ {        for y := min. Y; y < max. Y; y++ {            updatepoint (x,  Y)         }    }    return  mat}

Hxapp2
Translated 2 weeks ago

0 Person Top

top translation of good Oh!

In the above function, we begin to create a matrix with the same number of dimensions as the image. We continuously calculate the minimum cumulative energy per pixel from the leftmost column to the right column. For each pixel in a column, select the minimum accumulated energy point on the left or top left or bottom three points, and then add the energy of that point to the accumulated energy of the selected point. This approach allows us to not be so rigid that we can only linearly remove seam, resulting in greater flexibility and a better removal effect.

Then we can use this matrix to determine which pixels can be removed. We start with seam with a single point in each column and find the minimum cost seam.

type seam []pointtype point struct {    x, y int}//  FindLowestCostSeam uses an cost matrix to find the optimal  Seam for removal.func findlowestcostseam (Mat [][]float64)  Seam {     width, height := len (MAT),  len (mat[0])     seam :=  make ([]point, width)     min, y := math. maxfloat64, 0    for ind, val := range mat[width-1] {         if val < min {             min = val             y = ind        }     }    seam[width-1]&nbSp;= point{x: width - 1, y: y} 

Then we traverse the matrix from right to left. Each time the loop is traversed, the point is viewed, and its top and bottom three points are assigned to the seam with the minimum accumulated capacity.

for x := width - 2; x >= 0; x-- {     Left := mat[x][y]    up, down := math. Maxfloat64, math. maxfloat64    if y > 0 {         up = mat[x][y-1]    }    if y <  height-1 {        down = mat[x][y+1]     }    if up <= left && up <= down  {        seam[x] = point{x: x, y: y  - 1}        y = y - 1     } else if left <= up && left <= down {         seam[x] = Point{X: x, Y: y}         y = y    } else {         seam[x] = Point{X: x, Y: y + 1}         y = y + 1    }}

We visually examine our program logic by drawing seam on the image, confirming that seam is passing the area we expect. The image below is the first seam generated by the code above, drawn with a red line on the input image.

Hxapp2
Translated 2 weeks ago

0 Person Top

top translation of good Oh!

So the algorithm is to write a function that creates a new image that removes the computed seam, and puts the reduceheight function into a loop, and we can constantly zoom in and out of a single image by eliminating the smallest energy seam.

 removeseam creates a copy of the provided image, with the  pixels at // the points in the provided seam removed.func  removeseam (im image. Image, seam seam)  image. Image {    b := im. Bounds ()     out := image. Newrgba (image. Rect (0,&NBSP;0,&NBSP;B.DX (),  b.dy ()-1))     min, max := b.min, b. max    for _, point := range seam {         x := point. X        for y := min. Y; y < max. y; y++ {            if y ==  point. Y {                continue            }             if y > point. Y {                out. Set (X, y-1, im. at (x, y))             } else {                 out. Set (X, y, im. at (x, y))             }         }    }    return out}//  Reduceheight uses seam carving to reduce height of given image  n pixels.func reduceheight (im image. Image, n int)  image. image {    for x := 0; x < n; x++ {         Energy := generateenergymap (IM)         seam :=  Generateseam (energy)         im = removeseam (Im, seam)     }    return im}

Here is the effect of clearing 50 pixels. We can see that the areas with the least information (the sky) have been cleared away, and the areas with ships, water and buildings have not changed. Because the sky is basically the same, clearing these areas does not have much effect.

The final implementation code can be found on Github, and all functions can be exported, so you can study the changes the way you want.

Hxapp2
Translated 2 weeks ago

0 Person Top

top translation of good Oh!

This article simply introduces seam tailoring. On this topic, I highly recommend that you read the original paper, or video, which proves the possibilities of many applications. These applications include object removal, increasing the size of the image, or more.

This is not to say seam clipping has no warning. As discussed in the resource links above, this allows you to explore functions of many different functions, which are very difficult to handle pictures with very strict spatial relationships (such as human faces). This means that these things can be avoided, but we can not discuss them here first.

If you have any comments or questions about this article, please contact us for an algorithm or any other discussion you care about.

No if
Translated 3 weeks ago

0 Person Top

top translation of good Oh!

All translations in this article are for learning and communication purposes only, please be sure to indicate the translator, source, and link to this article.
Our translation work in accordance with the CC agreement, if our work has violated your rights and interests, please contact us promptly

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.