In: Computer Science
python: modify an image (just show me how to write the two functions described below)
1.One way to calculate the contrast between two colours is to calculate the brightness of the top pixel (the average of the red, green and blue components, with all three components weighted equally), and subtract the brightness of the pixel below it. We then calculate the absolute value of this difference. If this absolute value is greater than a threshold value, the contrast between the two pixels is high, so we change the top pixel's colour to black; otherwise, the contrast between the two pixels is low, so we change the top pixel's colour to whiteDevelop a filter named detect_edges that returns a copy of an image, in which the copy has been modified using the edge detection technique described in the preceding paragraphs. This filter has two parameters: an image and a threshold, which is a positive number.
2.As before, we calculate the contrast of two pixels by subtracting the brightness values of the pixels and calculating the absolute value of the difference. We change a pixel's colour to black only if the contrast between the pixel and the one below it is high (i.e., the absolute value of the difference exceeds the filter's threshold attribute) or the contrast between the pixel and the one to the right of it is high. Otherwise, we change the pixel's colour to white.
A simple algorithm for performing edge detection is: for every pixel that has a pixel below it, check the contrast between the two pixels. If the contrast is high, change the top pixel's colour to black, but if the contrast is low, change the top pixel's colour to white. For the bottom row (which has no pixels below it), simply set the pixel to white.
The below code modifies the original image using the two ways that has been specified in the question. I have used .shape[0] or .shape[1] to access the number of rows or columns in the image respectively. Also, I have created a copy of the original image by storing it in the imgCopy object and then manipulating the copy object.
For the first case we only check if the below pixel exists or not, if yes we find the absolute difference and then modify based on the difference else we set to white. For the second case, we check for the bottom pixel, if the pixel is modified there then we do not consider the right pixel (as flag is already true), and if it is modified in the right pixel then we do not modify in the final case. Please refer to comments in the code to understand it better.
CODE:-
import cv2 #to use the image processing capabilities in python
#Function that detects the edges by onyl analysing the below pixel (if present)
def detect_edges(img, threshold):
imgCopy = img #store a copy of the original image
#Traverse the image
for posX in range(0, imgCopy.shape[0]):
for posY in range(imgCopy.shape[1]):
pxTop = imgCopy[posX, posY] #store the top pixel
if(posX + 1 < imgCopy.shape[0]): #check if the bottom pixel is inside the image or not
pxBot = imgCopy[posX + 1, posY] #store the bottom pixel
avgTop = (int(pxTop[0]) + int(pxTop[1]) + int(pxTop[2]))/3 #take the average of the top pixel by weighing the red, green and blue pixel equally
avgBot = (int(pxBot[0]) + int(pxBot[1]) + int(pxBot[2]))/3 #take the average of the bottom pixel by weighing the red, green and blue pixel equally
if(abs(avgTop - avgBot) > threshold): #difference is greater than threshold
imgCopy[posX, posY] = [0, 0, 0] #assign black to the top pixel
else: #assign white to the top pixel
imgCopy[posX, posY] = [255, 255, 255]
else:
imgCopy[posX, posY] = [255, 255, 255] #in all the other cases assign white to the top pixel
return imgCopy #return the copy of image
#Function that detects the edges by analysing the below pixel or the right pixel (if present)
def detect_edgesRight(img, threshold):
imgCopy = img # store a copy of the original image
#Traverse the image
for posX in range(0, imgCopy.shape[0]):
for posY in range(imgCopy.shape[1]):
pxTop = imgCopy[posX, posY] # store the top pixel
flag = False #to store if the pixel is modified or not, if yes then we do not assign white else we do
# check if the bottom pixel is inside the image or not
if(posX + 1 < imgCopy.shape[0]):
pxBot = imgCopy[posX + 1, posY] # store the bottom pixel
# take the average of the top pixel by weighing the red, green and blue pixel equally
avgTop = (int(pxTop[0]) + int(pxTop[1]) + int(pxTop[2]))/3
# take the average of the bottom pixel by weighing the red, green and blue pixel equally
avgBot = (int(pxBot[0]) + int(pxBot[1]) + int(pxBot[2]))/3
if(abs(avgTop - avgBot) > threshold): # difference is greater than threshold
# assign black to the top pixel
imgCopy[posX, posY] = [0, 0, 0]
flag = True
#check for the right pixel only if the pixel is not modified already i.e. flag = False
if(posY + 1 < imgCopy.shape[1] and not flag):
pxRight = imgCopy[posX, posY+1] # store the right pixel
# take the average of the left pixel by weighing the red, green and blue pixel equally
avgTop = (int(pxTop[0]) + int(pxTop[1]) + int(pxTop[2]))/3
# take the average of the right pixel by weighing the red, green and blue pixel equally
avgRight = (int(pxRight[0]) + int(pxRight[1]) + int(pxRight[2]))/3
if(abs(avgTop - avgRight) > threshold): # difference is greater than threshold
# assign black to the left pixel
imgCopy[posX, posY] = [0, 0, 0]
flag = True #set flag to True as pixel is modified
if(not flag): #if pixel is not still modified by any case
imgCopy[posX, posY] = [255, 255, 255] #set to the pixel
return imgCopy # return the copy of image
img = cv2.imread("image.jpg")
cv2.imshow("Original", img)
cv2.imshow("Modified Image - Considering Only Below ", detect_edges(img, 5))
cv2.imshow("Modified Image - Considering Below & Right", detect_edgesRight(img, 5))
cv2.waitKey(0)
OUTPUT:-
The first image is the original image, the second image is the modified image using the first question and the last image is the image considering the below or right pixel.
Hope the answer helps you! Feel free to ask questions in comments and if the answer helped, please upvote!