Error splitting image in half using Python

Asked

Viewed 602 times

7

I’m trying to split an image in half using the code below, but I’m having a feedback error.

Code:

import cv2
import numpy as np

# Read the image
img = cv2.imread("IMD015.png")
width = img.shape

# Cut the image in half
width_cutoff = width / 2
s1 = img[:, width_cutoff]
s2 = img[:, width_cutoff:]

# Save each half
cv2.imsave("face1.png", s1)
cv2.imsave("face2.png", s2)

i1 = cv2.imread("face1.png")
i2 = cv2.imread("face2.png")
assert i1.mode == i2.mode, "Different kinds of images."
assert i1.size == i2.size, "Different sizes."

pairs = zip(i1.getdata(), i2.getdata())
if len(i1.getbands()) == 1:
    # for gray-scale jpegs
    dif = sum(abs(p1-p2) for p1,p2 in pairs)
else:
    dif = sum(abs(c1-c2) for p1,p2 in pairs for c1,c2 in zip(p1,p2))

ncomponents = i1.size[0] * i1.size[1] * 3
print ("Difference (percentage):"+ str((dif / 255.0 * 100) / ncomponents))

Error:

line 10, in <module>
    width_cutoff = width / 2
TypeError: unsupported operand type(s) for /: 'tuple' and 'int'

I know the error is in the division, but how do I correct?

2 answers

5


The error is very descriptive, you are taking a tuple and trying to divide by 2. You can only split a number, not a data set.

The documentation is very flawed, but in the end I found that the variable img.shape is actually receiving a tuple with some image data. You can’t take this tuple, but you can deconstruct it into variables and then take one of these variables and do the split if any of the elements is a number, and in fact I was able to infer that it is. So to get the width you should have done this:

_, width, _ = img.shape

I put in the Github for future reference.

Even if I don’t need the other elements I need to catch them, in case I used _ to discard them and not create a random variable.

  • worked out, that’s right. Very obgdo

  • now I am going through this error: line 19, in <module> assert I1.mode == I2.mode, "Different Kinds of images." Attributeerror: numpy.ndarray 'Object has no attribute 'mode'

  • 2

    This is another mistake and needs to be in another question. Anyway I think you need programming training. It seems that you’re trying to make complex codes without even knowing the basics, this doesn’t usually work.

  • It worked, only I realized that this split in the middle it gets in the whole picture, and I want to split in the middle according to my region of interest, which in my case is a skin spot. In this question that I asked, explain better what I am trying to develop, if you can help me in this, I thank you. https://stackoverflow.com/questions/53301086/how-to-identify-if-the-shapes-of-an-image-are-symmetric-or-asymmetric-using-open?noredirect=1#comment93492798_53301086

1

To complement the reply, other ways to get width.

.Hape from Opencv

With a print() in img.shape, it is possible to verify that a tuple is returned as follows: (altura, largura, número_de_canais)

Ex.: (600, 800, 3)

Then each value can be obtained with: height, width, channels = img.shape

Access the tuple element that corresponds to the width:

  • w = img.shape[1]
  • w = img.shape[-2]

Or the slicing Python can only be used to get height and width:

  • h, w = img.shape[:2]
  • h, w = img.shape[:-1]

Numpy

Width can be obtained with w = np.size(img, 1)

And the height with h = np.size(img, 0)

And the channel with c = np.size(img,2)

PIL

With the PIL library (Python Imaging Library)

from PIL import Image
im = Image.open('3mNqf.png')
print(im.size)
width, height = im.size
w = im.size[0]
w = im.size[-2]

Browser other questions tagged

You are not signed in. Login or sign up in order to post.