Pregunta

I am trying to flip an image horizontally.

From this:

Original Pic

To This:

Flipped Pic

But I keep getting it mirrored half way.

Like This:

Result I get

I am trying to reverse the x-axis index and I don't understand why it is being divided.

def flip(picture):
    height = getHeight(picture)
    width = getWidth(picture)
    newPicture = makeEmptyPicture(width, height)
    x2 = width-1
    for x in range(0, width):
        y2 = 0
        for y in range(0, height):
            pxl = getPixel(picture, x, y)
            newPxl = getPixel(picture, x2, y2)
            color = getColor(pxl)
            setColor(newPxl, color)
            y2 = y2+1
        x2 = x2-1
    return picture

The rest of my code:

def d():    
    f = pickAFile()
    picture = makePicture(f)        
    newPicture = copy(picture)        
    writePictureTo(newPicture, r"D:\FOLDER\newPic4.jpg")
    explore(newPicture)
¿Fue útil?

Solución 3

In your flip() function (like in any function), as mentioned by the other answers, you return picture which is the image passed as a parameter of the function but is defined in d()...

It is a matter of scope of the variables, so I invite you to have a look again at the discussion we had here.

Here, you had two choices (you made a melting between the two):

  • Modifying directly the picture given as parameter
  • Creating a newPicture, modifying it, and finally returning it

Details about the 2d option :

The important thing here is that the picture variable belongs to the d() function (d() is the scope of it). In the mean time the newPicture variable belongs to the flip() function (flip() is its scope). So the life time of the newPicture is flip() (i.e. it is destroyed as soon as you terminate the execution of the flip() function, while returning). And d() doesn't know anything about this newPicture, unless you return it to d().

So, in short (assuming we are talking about the second option):

1) Create a function that takes a picture as parameter (flip())

2) Inside flip(), create a local variable newPicture and modify that one only, such that the original picture remains unchanged

3) Return the newly updated newPicture to the parent scope. Here d() is calling flip(), so it is the parent scope. We have to create a 3d variable (which belongs to d() scope), to keep a hand on what was returned by flip():

def flip(picture)
    # Create newPicture
    # Modify newPicture (using the information from the "picture" parameter)
    setColor(newPicture, ...)
    ...
    return newPicture

def d():
    file = PickAFile()
    original_pic = makePicture(file) 
    finalNewPicture = flip(original_pic)     # {1}
    show(finalNewPicture)

{1}: Here we assign the value returned by flip (i.e. newPicture) to the variable of higher scope finalNewPicture (handler)...

I hope it helps you to understand the logic behind this. It is like Russian dolls: newPicture is used inside flip(), which is used inside d(), ...


EDIT :

I also want to give an explanation about the 1st option...

1) Create a function that takes a picture as parameter (flip())

2) Inside flip(), modify directly the higher scoped picture variable

3) Do not return anything from flip()

This would result in this :

def flip(picture)
    # Simply modify the variable "picture", given as a parameter
    setColor(picture, ...)
    ...
    # Do not return anything

def d():
    file = PickAFile()
    original_pic = makePicture(file) 
    flip(original_pic)                     # {1}
    show(original_pic)

{1}: Here flip() made the changes directly on the input picture, so we can display the original modified picture directly (original_pic). No need for an intermediate handler variable.


Code for option 1 : (as you already have it working for option 2)

def flip(picture):
  height = getHeight(picture)
  width = getWidth(picture)

  x2=width-1
  for x in range(0, width/2):   # Only process the half way
    y2=0
    for y in range(0, height):
      # swap pix and pix2
      pxl = getPixel(picture, x, y)
      pxl2 = getPixel(picture, x2, y2)
      color = getColor(pxl)
      color2 = getColor(pxl2)
      setColor(pxl2, color)
      setColor(pxl, color2)
      y2=y2+1
    x2=x2-1  

def d():    
  f = pickAFile()
  original_picture = makePicture(f)        
  flip2(original_picture)        
  show(original_picture)

d()

Note : flip could have been widely simplified as follows :

def flip2(picture):
  height = getHeight(picture)
  width = getWidth(picture)

  for x in range(0, width/2):   # Only process the half way
    for y in range(0, height):
      # swap pix and pix2
      pxl = getPixel(picture, x, y)
      pxl2 = getPixel(picture, width-1-x, y)
      color = getColor(pxl)
      color2 = getColor(pxl2)
      setColor(pxl2, color)
      setColor(pxl, color2)

Otros consejos

You are changing the pixels in the original picture instead of the newly created newPicture. Also, you are returning the original (now modified) picture.

You should have

newPxl = getPixel(newPicture, x2,y2)

and you should end with

return newPicture

Also, I think your code flips the image around the horizontal axis, not the vertical as your images show.

def flip(picture):
  height = getHeight(picture)
  width = getWidth(picture)
  newPicture = makeEmptyPicture(width, height)
  for x in range(width):
    for y in range(height):
      color = getColor(getPixel(picture, x, y))
      setColor(getPixel(newPicture, width-1-x, y), color)
  return newPicture

How about this? I just removed the x2/y2 stuff which didn't seem necessary to me. Otherwise it should work this way. I found no true bug in your code, just the returning of the picture instead of newPicture at the end. But that should not have lead to a mirroring either.

OpenCV provides a function to flip an  image.

void flip(array src, array dst, int flipCode)

Flips a 2D array around vertical, horizontal or both axes.

Parameters:

  • src – The source Array
  • dst – The destination array; will have the same size and same type as src
  • flipCode – Specifies how to flip the array: 0 means flipping around the x-axis, positive (e.g., 1) means flipping around y-axis, and negative (e.g., -1) means flipping around both axes.The function flip flips the array in one of three different ways (row and column indices are 0-based).

Example code:

cv.flip(original_image,flipped_image,1);

Edit: You can also assign the flipped image:

flipped_image = cv2.flip(src=original_image, flipCode=1)
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top