Replace color in image measured by Euclidean distance











up vote
7
down vote

favorite
1












This script replaces the red hair in image to black color (replace one color to another)





Three major parts in this script




  • Not just replace color red to black, I hope the output image looks natural, so I will replace the color close to red to black. This "close" is measured by Euclidean distance.


  • And not just replace by black color, user can modify the red color's r, g, b value separately, like add more green.


  • Choose the area to be changed, rather than change the whole picture





Suggestions I am looking for:




  • I did some NumPy practice before, so any suggestions about NumPy are welcome.


  • I think the code to replace target area is not so elegant, I am not quite sure about this part:



    (c1, r1), (c2, r2) = area
    for i in range(r1, r2+1):
    l, r = i*h+c1, i*h+c2+1
    data[l:r,:k][D[l:r]] = modification(data[l:r,:k][D[l:r]])





Full code:



import numpy as np
from PIL import Image
from scipy.spatial.distance import cdist

def replace_corlor(image, original_corlor, modification, area=None, distance=1000, output="new_test.jpg"):
print("[*] START Replace Color")
img = Image.open(image)
data = np.asarray(img, dtype="int32")
w,h,k = data.shape
data = np.reshape(data, (w*h,k))
distMatrix = cdist(data, np.array([original_corlor]))
D = distMatrix<=distance
D = np.reshape(D,w*h)
if area is None:
data[:,:k][D] = modification(data[:,:k][D])
else:
(c1, r1), (c2, r2) = area
for i in range(r1, r2+1):
l, r = i*h+c1, i*h+c2+1
data[l:r,:k][D[l:r]] = modification(data[l:r,:k][D[l:r]])
data = np.reshape(data, (w,h,k))
img = Image.fromarray(np.asarray(np.clip(data, 0, 255), dtype="uint8"), "RGB")
img.save(output)
print("[*] DONE Replace Color")

if __name__ == "__main__":
def modification(color):
return color * [2,0,0]
# return [255,0,0]
replace_corlor("test.jpg",(36,35,30),modification, ((0,0),(400,100)))









share|improve this question




















  • 1




    I have no comments on your code, your Python is better than mine. :) But for color modification you could use the distance to the original_color value. The larger this distance (and the closer the distance is to the distance threshold), the less you modify the color. This way, you will get a smoother transition at the edges of the red region.
    – Cris Luengo
    10 hours ago










  • @CrisLuengo Ah good advice!, thank you ^^
    – Aries_is_there
    10 hours ago















up vote
7
down vote

favorite
1












This script replaces the red hair in image to black color (replace one color to another)





Three major parts in this script




  • Not just replace color red to black, I hope the output image looks natural, so I will replace the color close to red to black. This "close" is measured by Euclidean distance.


  • And not just replace by black color, user can modify the red color's r, g, b value separately, like add more green.


  • Choose the area to be changed, rather than change the whole picture





Suggestions I am looking for:




  • I did some NumPy practice before, so any suggestions about NumPy are welcome.


  • I think the code to replace target area is not so elegant, I am not quite sure about this part:



    (c1, r1), (c2, r2) = area
    for i in range(r1, r2+1):
    l, r = i*h+c1, i*h+c2+1
    data[l:r,:k][D[l:r]] = modification(data[l:r,:k][D[l:r]])





Full code:



import numpy as np
from PIL import Image
from scipy.spatial.distance import cdist

def replace_corlor(image, original_corlor, modification, area=None, distance=1000, output="new_test.jpg"):
print("[*] START Replace Color")
img = Image.open(image)
data = np.asarray(img, dtype="int32")
w,h,k = data.shape
data = np.reshape(data, (w*h,k))
distMatrix = cdist(data, np.array([original_corlor]))
D = distMatrix<=distance
D = np.reshape(D,w*h)
if area is None:
data[:,:k][D] = modification(data[:,:k][D])
else:
(c1, r1), (c2, r2) = area
for i in range(r1, r2+1):
l, r = i*h+c1, i*h+c2+1
data[l:r,:k][D[l:r]] = modification(data[l:r,:k][D[l:r]])
data = np.reshape(data, (w,h,k))
img = Image.fromarray(np.asarray(np.clip(data, 0, 255), dtype="uint8"), "RGB")
img.save(output)
print("[*] DONE Replace Color")

if __name__ == "__main__":
def modification(color):
return color * [2,0,0]
# return [255,0,0]
replace_corlor("test.jpg",(36,35,30),modification, ((0,0),(400,100)))









share|improve this question




















  • 1




    I have no comments on your code, your Python is better than mine. :) But for color modification you could use the distance to the original_color value. The larger this distance (and the closer the distance is to the distance threshold), the less you modify the color. This way, you will get a smoother transition at the edges of the red region.
    – Cris Luengo
    10 hours ago










  • @CrisLuengo Ah good advice!, thank you ^^
    – Aries_is_there
    10 hours ago













up vote
7
down vote

favorite
1









up vote
7
down vote

favorite
1






1





This script replaces the red hair in image to black color (replace one color to another)





Three major parts in this script




  • Not just replace color red to black, I hope the output image looks natural, so I will replace the color close to red to black. This "close" is measured by Euclidean distance.


  • And not just replace by black color, user can modify the red color's r, g, b value separately, like add more green.


  • Choose the area to be changed, rather than change the whole picture





Suggestions I am looking for:




  • I did some NumPy practice before, so any suggestions about NumPy are welcome.


  • I think the code to replace target area is not so elegant, I am not quite sure about this part:



    (c1, r1), (c2, r2) = area
    for i in range(r1, r2+1):
    l, r = i*h+c1, i*h+c2+1
    data[l:r,:k][D[l:r]] = modification(data[l:r,:k][D[l:r]])





Full code:



import numpy as np
from PIL import Image
from scipy.spatial.distance import cdist

def replace_corlor(image, original_corlor, modification, area=None, distance=1000, output="new_test.jpg"):
print("[*] START Replace Color")
img = Image.open(image)
data = np.asarray(img, dtype="int32")
w,h,k = data.shape
data = np.reshape(data, (w*h,k))
distMatrix = cdist(data, np.array([original_corlor]))
D = distMatrix<=distance
D = np.reshape(D,w*h)
if area is None:
data[:,:k][D] = modification(data[:,:k][D])
else:
(c1, r1), (c2, r2) = area
for i in range(r1, r2+1):
l, r = i*h+c1, i*h+c2+1
data[l:r,:k][D[l:r]] = modification(data[l:r,:k][D[l:r]])
data = np.reshape(data, (w,h,k))
img = Image.fromarray(np.asarray(np.clip(data, 0, 255), dtype="uint8"), "RGB")
img.save(output)
print("[*] DONE Replace Color")

if __name__ == "__main__":
def modification(color):
return color * [2,0,0]
# return [255,0,0]
replace_corlor("test.jpg",(36,35,30),modification, ((0,0),(400,100)))









share|improve this question















This script replaces the red hair in image to black color (replace one color to another)





Three major parts in this script




  • Not just replace color red to black, I hope the output image looks natural, so I will replace the color close to red to black. This "close" is measured by Euclidean distance.


  • And not just replace by black color, user can modify the red color's r, g, b value separately, like add more green.


  • Choose the area to be changed, rather than change the whole picture





Suggestions I am looking for:




  • I did some NumPy practice before, so any suggestions about NumPy are welcome.


  • I think the code to replace target area is not so elegant, I am not quite sure about this part:



    (c1, r1), (c2, r2) = area
    for i in range(r1, r2+1):
    l, r = i*h+c1, i*h+c2+1
    data[l:r,:k][D[l:r]] = modification(data[l:r,:k][D[l:r]])





Full code:



import numpy as np
from PIL import Image
from scipy.spatial.distance import cdist

def replace_corlor(image, original_corlor, modification, area=None, distance=1000, output="new_test.jpg"):
print("[*] START Replace Color")
img = Image.open(image)
data = np.asarray(img, dtype="int32")
w,h,k = data.shape
data = np.reshape(data, (w*h,k))
distMatrix = cdist(data, np.array([original_corlor]))
D = distMatrix<=distance
D = np.reshape(D,w*h)
if area is None:
data[:,:k][D] = modification(data[:,:k][D])
else:
(c1, r1), (c2, r2) = area
for i in range(r1, r2+1):
l, r = i*h+c1, i*h+c2+1
data[l:r,:k][D[l:r]] = modification(data[l:r,:k][D[l:r]])
data = np.reshape(data, (w,h,k))
img = Image.fromarray(np.asarray(np.clip(data, 0, 255), dtype="uint8"), "RGB")
img.save(output)
print("[*] DONE Replace Color")

if __name__ == "__main__":
def modification(color):
return color * [2,0,0]
# return [255,0,0]
replace_corlor("test.jpg",(36,35,30),modification, ((0,0),(400,100)))






python python-3.x image numpy






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 10 hours ago









Cris Luengo

2,299319




2,299319










asked Nov 11 at 10:27









Aries_is_there

56829




56829








  • 1




    I have no comments on your code, your Python is better than mine. :) But for color modification you could use the distance to the original_color value. The larger this distance (and the closer the distance is to the distance threshold), the less you modify the color. This way, you will get a smoother transition at the edges of the red region.
    – Cris Luengo
    10 hours ago










  • @CrisLuengo Ah good advice!, thank you ^^
    – Aries_is_there
    10 hours ago














  • 1




    I have no comments on your code, your Python is better than mine. :) But for color modification you could use the distance to the original_color value. The larger this distance (and the closer the distance is to the distance threshold), the less you modify the color. This way, you will get a smoother transition at the edges of the red region.
    – Cris Luengo
    10 hours ago










  • @CrisLuengo Ah good advice!, thank you ^^
    – Aries_is_there
    10 hours ago








1




1




I have no comments on your code, your Python is better than mine. :) But for color modification you could use the distance to the original_color value. The larger this distance (and the closer the distance is to the distance threshold), the less you modify the color. This way, you will get a smoother transition at the edges of the red region.
– Cris Luengo
10 hours ago




I have no comments on your code, your Python is better than mine. :) But for color modification you could use the distance to the original_color value. The larger this distance (and the closer the distance is to the distance threshold), the less you modify the color. This way, you will get a smoother transition at the edges of the red region.
– Cris Luengo
10 hours ago












@CrisLuengo Ah good advice!, thank you ^^
– Aries_is_there
10 hours ago




@CrisLuengo Ah good advice!, thank you ^^
– Aries_is_there
10 hours ago















active

oldest

votes











Your Answer





StackExchange.ifUsing("editor", function () {
return StackExchange.using("mathjaxEditing", function () {
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
});
});
}, "mathjax-editing");

StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "196"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














 

draft saved


draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f207415%2freplace-color-in-image-measured-by-euclidean-distance%23new-answer', 'question_page');
}
);

Post as a guest





































active

oldest

votes













active

oldest

votes









active

oldest

votes






active

oldest

votes
















 

draft saved


draft discarded



















































 


draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f207415%2freplace-color-in-image-measured-by-euclidean-distance%23new-answer', 'question_page');
}
);

Post as a guest




















































































Popular posts from this blog

Morgemoulin

Scott Moir

Souastre