Sunday, November 15, 2015

CST 205 Week 3 - Image Portfolio

Image Portfolio

Below are some examples of the functions I've written for my Multimedia Design & Programming course at CSUMB (in Python). 

Week 1 - Lab #3

Rose-colored glasses

The rose colored glasses filter looks at each pixel in an image and increases the red by 25%, decreases the blue by 25% and decreases the green by 25%. This gives the picture a nice, pink tint. Making the pictures pink and not red was a bit challenging.
def roseColoredGlasses(image):
  pixels = getPixels(image)
  for pixel in pixels:
    setRed(pixel, getRed(pixel) * 1.25)
    setBlue(pixel, getBlue(pixel) * 0.75)
    setGreen(pixel, getGreen(pixel) * 0.75)
  return image
original:
 result:

Negative

The negative filter looks at each pixel in the image and changes the RBG value to be the difference between the possible value (always 255) and the actual value. This results in the exact opposite of the original image. This one felt pretty simple and straightforward to me.
def makeNegative(originalImage):
  pixels = getPixels(originalImage)
  for pixel in pixels:
    setRed(pixel, 255 - getRed(pixel))
    setBlue(pixel, 255 - getBlue(pixel))
    setGreen(pixel, 255 - getGreen(pixel))
  return originalImage
original:
result:

Better black and white

The better black and white filter looks at each of the RBG values in a pixel within an image. It reduces red to 29.9%, blue to 11.4%, and green to 58.7%. The outcome of that is combined at set for each color in the picture. I don't remember thinking this was difficult at the time, but looking at it again makes me unsure that it's correct.
def betterBnW(image):
  pixels = getPixels(image)
  for pixel in pixels:
    colorVal = getRed(pixel) * 0.299
    colorVal = colorVal + getBlue(pixel) * 0.114
    colorVal = colorVal + getGreen(pixel) * 0.587
    setRed(pixel, colorVal)
    setBlue(pixel, colorVal)
    setGreen(pixel, colorVal)
  return image
original: 
 result:

Week 2 - Lab #4

Bottom-to-top mirror

This image manipulation iterates through all of the pixels on the bottom half of the image and updates each pixel that is the perfect opposite (on the top) of the current pixel to match, resulting in the bottom-to-top mirror image. The mirror manipulations all just required some consideration before implementing them.
def bottomToTopMirror(image):
  totalX = getWidth(image) - 1
  totalY = getHeight(image) - 1
  for x in range(0, totalX):
    for y in range(totalY/2, totalY):
      currentPixel = getPixel(image, x, y)
      topPixel = getPixel(image, x, totalY - y)
      color = getColor(currentPixel)
      setColor(topPixel, color)
  return image
original: 
 result:

Shrink

The shrink image manipulation creates a new canvas that is half the width and half the height of the original image. It then picks up every other pixel and copies it into the new canvas. The new canvas is returned, which makes this method appear to shrink the original image. The difficult step in this one was understanding what we're picking up and what we're copying to get the desired result.
def shrink(image):
  width = getWidth(image)
  height = getHeight(image)
  pic = makeEmptyPicture(width/2, height/2)
  for x in range (0, width-1, 2):
    for y in range (0, height-1, 2):
      color = getColor(getPixel(image, x, y))
      setColor(getPixel(pic, x/2, y/2), color)
  return pic
original:

 result:

Collage

The collage portion of the assignment took me a lot longer to do than all of our other assignments, mostly because I had to figure out the dimensions of the images after shrinking them to size and/or rotating them and then spend time planning where to place them and in which order since exceeding the page size results in an error. I ended up using a tool that works with google drive called draw.io to assist with this. Also, I'd like to note that I had all of the images in a particular order that I was importing them, but now I see that I should have just created them with the file path instead of selecting them every time. Some of the functions I used to make this collage method are listed above. For those that aren't, they're listed below the makeCollage method.
def makeCollage():
  collage =  makeEmptyPicture(1260, 900) # 5x7
  pic1 = makePicture(pickAFile())
  pic2 = makePicture(pickAFile())
  pic3 = makePicture(pickAFile())
  pic4 = makePicture(pickAFile())
  pic5 = makePicture(pickAFile())
  pic6 = makePicture(pickAFile())
  pic7 = makePicture(pickAFile())
  pic8 = makePicture(pickAFile())
  pic9 = makePicture(pickAFile())
  pic3Rotated = rotatePic(pic3)
  pic6Rotated = rotatePic(pic6)
  pic7Resized = shrink(shrink(pic7))
  pic8Resized = shrink(shrink(shrink(pic8)))
  pyCopy(pic6Rotated, collage, 672, 507)
  pyCopy(roseColoredGlasses(pic5), collage, 886, 0)
  pyCopy(makeNegative(pic9), collage, 0, 0)
  pyCopy(pic2, collage, 50, 204)
  pyCopy(moreRed(pic7Resized, 50), collage, 0, 578)
  pyCopy(quadrupleMirror(pic1), collage, 418, 480)
  pyCopy(noBlue(pic3Rotated), collage, 255, 0)
  pyCopy(betterBnW(pic8Resized), collage, 693, 90)
  pyCopy(leftToRightMirror(pic4), collage, 325, 290)
  return collage

def moreRed(image, amount):
  incPercent = 1 + amount * 0.01
  pixels = getPixels(image)
  for pixel in pixels:
    redAmount = getRed(pixel)
    # Set red amount at max red value if it is over the highest value possible
    if redAmount > 255:
      redAmount = 255
    setRed(pixel, redAmount * incPercent)
  return image

def quadrupleMirror(image):
  totalX = getWidth(image) - 1
  totalY = getHeight(image) - 1
  for x in range(0, (totalX/2)):
    for y in range(0, (totalY/2)):
      currentPixel = getPixel(image, x, y)
      rightPixel = getPixel(image, totalX - x, y)
      bottomPixel = getPixel(image, x, totalY - y)
      diagonalPixel = getPixel(image, totalX - x, totalY - y)
      color = getColor(currentPixel)
      setColor(rightPixel, color)
      setColor(bottomPixel, color)
      setColor(diagonalPixel, color)
  return image

def noBlue(image):
  pixels = getPixels(image)
  for pixel in pixels:
    setBlue(pixel, 0)
  return image

def leftToRightMirror(image):
  totalX = getWidth(image) - 1
  totalY = getHeight(image) - 1
  for x in range(0, (totalX/2)):
    for y in range(0, totalY):
      currentPixel = getPixel(image, x, y)
      rightPixel = getPixel(image, totalX - x, y)
      color = getColor(currentPixel)
      setColor(rightPixel, color)
  return image
result:

Red-eye Reduction

This function looks at every red pixel within a certain range and determines if it has a particular amount of red in the pixel. If it does, the color of the pixel is changed to the desired color indicated by the parameter color (in this case, black).
def eyeCorrection(color):
  image = makePicture('/Users/brittanymazza/Desktop/redeye.jpg')
  for x in range (0, getWidth(image)-1):
    for y in range (0, getHeight(image)-1):
      currentPixel = getPixel(image, x, y)
      currentColor = getColor(currentPixel)
      if (x > 155 and x < 295) and (y > 160 and y < 215):
        if distance(currentColor, red) < 150:
          setColor(currentPixel, color)
  return image
original:
result:

Color Art-i-fy

I find this method embarrassing to put up, but it does what it should. Ideally the if/else statements would be extracted out into another method because they all do the same thing. The logic behind this was easy, but the outcome of my method is not visually appealing. What happens with this one is that the red, blue, and green values for each pixel are set to a particular value if they're within a certain range. Value from 0-63 is set to 31, 64-127 is set to 95, 128-191 is set to 159, and 192-255 is set to 233.
def artify(image):
  for x in range (0, getWidth(image)-1):
    for y in range (0, getHeight(image)-1):
      currentPixel = getPixel(image, x, y)
      redColor = getRed(currentPixel)
      greenColor = getGreen(currentPixel)
      blueColor = getBlue(currentPixel)
      if (redColor < 64):
        redColor = 31
      elif (redColor > 63 and redColor < 128):
        redColor = 95
      elif (redColor > 127 and redColor < 192):
        redColor = 159
      elif (redColor > 191 and redColor < 256):
        redColor = 223
      if (greenColor < 64):
        greenColor = 31
      elif (greenColor > 63 and greenColor < 128):
        greenColor = 95
      elif (greenColor > 127 and greenColor < 192):
        redColor = 159
      elif (greenColor > 191 and greenColor < 256):
        greenColor = 223
      if (blueColor < 64):
        blueColor = 31
      elif (blueColor > 63 and blueColor < 128):
        blueColor = 95
      elif (blueColor > 127 and blueColor < 192):
        blueColor = 159
      elif (blueColor > 191 and blueColor < 256):
        blueColor = 223
      setRed(currentPixel, redColor)
      setGreen(currentPixel, greenColor)
      setBlue(currentPixel, blueColor)
  return image
original:
result:

Green screen

The green screen method I made, called chromaKey, looks at each pixel in the green screen image, looking for pixels with a particular amount of green. If there's enough green, it replaces the color of the pixel with the matching one from the background image. This method does not work when the background is smaller than the green screen image.
def chromaKey(image, background):
  for x in range (0, getWidth(image)-1):
    for y in range (0, getHeight(image)-1):
      currentPixel = getPixel(image, x, y)
      currentColor = getColor(currentPixel)
      if distance(currentColor, green) < 150.0:
        bgColor = getColor(getPixel(background, x, y))
        setColor(currentPixel, bgColor)
  repaint(image) # This is not necessary
  return image
originals: 
 result:

Week 3 - Lab #7

Home made Thanksgiving

Several functions were added for this card to do specific things, like adding the sunshine layer, grass layer, and turkey. The images were cut out based on colors (white or black), similar to how we did the green screen in earlier labs. They're all called from the original, generateCard4, method. The mediaPath variable was set to the directory where the images are (using setMediaPath method), which is why the full path is not shown.
def generateCard4():
  card = getBlankCard()
  addSunshine(card)
  addGrass(card)
  applyTurkey1(card)
  addQuestionableHappyThanksgivingText(card)
  return card

def getBlankCard():
  # Create 5x7 card
  return makeEmptyPicture(945, 675)

# Add "Happy Thanksgiving?" text to card.
def addQuestionableHappyThanksgivingText(card):
  text = "Happy Thanksgiving?"
  textStyle = makeStyle(serif, bold, 13)
  startX = (getWidth(card)/20)*11
  startY = (getHeight(card)/20)*7
  textColor = makeColor(153, 0, 0)
  addTextWithStyle(card, startX, startY, text, textStyle, textColor)

# Apply the turkey holding the sign to a card.
def applyTurkey1(card):
  turkeyPic = makePicture("turkey1.jpg")
  # Apply to center of card.
  startX = (getWidth(card) - getWidth(turkeyPic))/2
  startY = (getHeight(card) - getHeight(turkeyPic))/2
  for x in range(0, getWidth(turkeyPic)-1):
    for y in range(0, getHeight(turkeyPic)-1):
      turkeyPixel = getPixel(turkeyPic, x, y)
      turkeyPixelColor = getColor(turkeyPixel)
      # Don't copy over white pixels to treat turkey background as if it
      # were transparent.
      if distance(turkeyPixelColor, white) > 0.75:
        cardPixel = getPixel(card, startX + x, startY + y)
        setColor(cardPixel, turkeyPixelColor)

# Add sunshine to card.
def addSunshine(card):
  sunshinePic = makePicture("sunshine.jpg")
  # Apply to top of card.
  for x in range(0, getWidth(sunshinePic)):
    for y in range(0, getHeight(sunshinePic)):
      pixel = getPixel(card, x, y)
      sunshineColor = getColor(getPixel(sunshinePic, x, y))
      setColor(pixel, sunshineColor)

# Add grass to card.
def addGrass(card):
  grassPic = makePicture("grass.png")
  # Apply to base of card.
  startY = getHeight(card) - getHeight(grassPic)
  for x in range(0, getWidth(grassPic)):
    for y in range(0, getHeight(grassPic)):
      grassColor = getColor(getPixel(grassPic, x, y))
      # Only color if grass image doesn't look black, which is how 
      # getColor interprets the transparency.
      if distance(grassColor, black) > 0.25:
        setColor(getPixel(card, x, startY + y), grassColor)

originals:
result:

Week 3 - Image Portfolio Assignment

Line drawing

The line drawing method looks at each pixel in an image and compares it to the pixel to the right of it as well as the picture below it and takes into consideration the luminance difference between the two pixels. Depending on the result and the contrast variance variable passed it, it either sets the pixel to black or white. This creates a "line drawing" appearance. In the examples below I've used a contrast variance variable of 3. When we're at a pixel at the very right edge, we only consider the pixel below it. Likewise, when we're at a pixel at the very bottom edge, we only consider the pixel to the right of it. However, we can't compare the pixel to anything once we get to the ver right, bottom corner, so I decided to just look at if it's closer to black or white. I've split the method into 5 separate methods for better readability and reusability.
def lineDrawing(image, contrast):
  image = BnW(image)
  maxWidth = getWidth(image)-1
  maxHeight = getHeight(image)-1
  isBlack = false
  for x in range (0, maxWidth):
    for y in range (0, maxHeight):
      pixel = getPixel(image, x, y)
      isBlack = shouldBeBlack(pixel, x, y, maxWidth, maxHeight, contrast)
      setBlackOrWhite(pixel, isBlack)
  return image

# Return true/false indicating if the pixel should be black
def shouldBeBlack(pixel, x, y, maxWidth, maxHeight, contrast):
  if x == maxWidth and y == maxHeight:
    return getLuminance(pixel) > (255 / 2)
  elif x == maxWidth:
    return isSignificantDiff(pixel, getPixel(image, x, y+1), contrast)
  elif y == maxHeight:
    return isSignificantDiff(pixel, getPixel(image, x+1, y), contrast)
  else:
    isSigRight = isSignificantDiff(pixel, getPixel(image, x+1, y), contrast)
    isSigDown = isSignificantDiff(pixel, getPixel(image, x, y+1), contrast)
    return isSigRight and isSigDown
  
# Return true/false indicating if there's a significant difference
def isSignificantDiff(pixel, comparePixel, contrast):
  diff = abs(getLuminance(pixel) - getLuminance(comparePixel))
  return diff > contrast

# Return the luminance value (0-255) of a pixel
def getLuminance(pixel):
  return (getRed(pixel) + getBlue(pixel) + getGreen(pixel)) / 3
  
# Set the pixel to black or white depending on the isBlack value passed in
def setBlackOrWhite(pixel, isBlack):
  if isBlack:
    setColor(pixel, black)
  else:
    setColor(pixel, white)
original: 
 result:


No comments:

Post a Comment