Error in sepia effect opencv python

I'm trying to create a filter which will create a sepia look for all pictures. But I get some spots in my filtered image which are blue and cyan. I think it might be overflow but I tried to account for that and it didnt give me the affect I was looking for. I'm not sure whats wrong. The link to original is at https://www.dropbox.com/s/pd0esc8tef3smae/Lampard.jpg and after the modification, it becomes https://www.dropbox.com/s/f9n9lrhoi1qqs53/Lampard_blue.jpg

def filter3(path, cv2):
cv2.destroyAllWindows()
cv2.namedWindow("Filter 3")
img = cv2.imread(path, cv2.IMREAD_UNCHANGED) 
newImg = img
(i,j,k) = img.shape
for x in xrange(i):
    for y in xrange(j):
        b = img[x,y,0]
        g = img[x,y,1]
        r = img[x,y,2]
        if(k == 4):
            newImg[x,y,0] = np.uint16(b * 0.272 + g * 0.534 + r * 0.131)
            newImg[x,y,1] = np.uint8(b * .349 + g * 0.686 + r * 0.168)
            newImg[x,y,2] = np.uint8(b * 0.393 + g * 0.769 + r * 0.189)
            # newB = np.uint16(b * 0.272 + g * 0.534 + r * 0.131)
            # newG = np.uint16(b * .349 + g * 0.686 + r * 0.168)
            # newR = np.uint16(b * 0.393 + g * 0.769 + r * 0.189)
            # if(newB > 255):
            #   newImg[x,y,0] = np.uint8(255)
            # else: 
            #   newImg[x,y,0] = np.uint8(newB)
            # if(newG > 255):
            #   newImg[x,y,1] = np.uint8(255) 
            # else: 
            #   newImg[x,y,1] = np.uint8(newB)
            # if(newR > 255):
            #   newImg[x,y,2] = np.uint8(255) 
            # else: 
            #   newImg[x,y,2] = np.uint8(newB)

            newImg[x,y,3] = img[x,y,3]
        else:
            newImg[x,y,0] = np.uint16(b * 0.272 + g * 0.534 + r * 0.131)
            newImg[x,y,1] = np.uint8(b * .349 + g * 0.686 + r * 0.168)
            newImg[x,y,2] = np.uint8(b * 0.393 + g * 0.769 + r * 0.189)
            # if(newB > 255):
            #   newImg[x,y,0] = np.uint8(0)
            # else: 
            #   newImg[x,y,0] = np.uint8(newB)
cv2.imshow("Filter 3", newImg)
return newImg

Answers


I don't know python but you can refer below C++ code works fine for me.

Mat src=imread("Lampard.jpg",1);
Mat SepiaKernel = (Mat_<float>(4,4) << 0.189, 0.769, 0.393, 0,\
                                       0.168, 0.686, 0.349, 0,\
                                       0.131, 0.534, 0.272, 0,\
                                       0.000, 0.000, 0.000, 1);
Mat dst;
transform(src, dst, SepiaKernel);
imshow("src",src);
imshow("sepia",dst);
waitKey();

Result:-


In my opinion problem is with types. Python thinks that after operation you want to integer. Each channel has 8 bits. After calculation when you will get value 256 (100000001) python will read only first 8 bits (00000001). Because of that you have a little bit strange image. In my case works this code:

import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('lena.jpg')
newImage = cv2.imread('lena.jpg')
i, j, k = img.shape
for x in xrange(i):
    for y in xrange(j):
    R = img[x,y,2] * 0.393 + img[x,y,1] * 0.769 + img[x,y,0] * 0.189
    G = img[x,y,2] * 0.349 + img[x,y,1] * 0.686 + img[x,y,0] * 0.168
    B = img[x,y,2] * 0.272 + img[x,y,1] * 0.534 + img[x,y,0] * 0.131
    if R > 255:
        newImage[x,y,2] = 255
    else:
        newImage[x,y,2] = R
    if G > 255:
        newImage[x,y,1] = 255
    else:
        newImage[x,y,1] = G
    if B > 255:
        newImage[x,y,0] = 255
    else:
        newImage[x,y,0] = B

cv2.imshow('image',newImage)
cv2.waitKey(0)
cv2.destroyAllWindows()

Maybe it's not nice code, but I'm not familiar with Python.


Need Your Help

Keep UITableView scrolled to bottom as new rows are added

iphone uitableview

Part of an app I'm working on involves a messaging interface which I'm trying to make similar to the iOS Messages app's interface. When new messages are received or sent, I'd like the table view to

contact form 7 thank you page with summary

wordpress contact contact-form-7

I need a customized thank you page which will be showed after submitting contact form (contactform7), the form will show the name and email address entered by user.