(Python 3 / OpenCV) cv2.imwrite returns a Boolean and not the image object - python-3.x

I am trying to edit a color image and return the gray scale of that image. Which I am able to do but I can only get to it by hard coding the name. After a little print statement debugging I found that the return statement I was using in only returning a boolean.
def change_to_gray_scale(path):
color_image = path
img = cv2.imread(color_image, 0)
gray_img = cv2.imwrite(color_image.strip(".jpg") + "_colorless.jpg", img)
return gray_img # Returns a Boolean and not "new_image_colorless.jpg"
What I wanted to do it get it to return the new image but I have had no luck. I have been at this for a few hours now and just might be making a silly little mistake. So while I take a break I thought I would let some other eyes take a look at it.
Thanks for the help!

For the time being I have just decided to go with a little work around string formatting. CV2 documentation for C says that imwrite returns a bool so I'm just going to assume that is the same for python.
Here is the work around I came up with.
image_str = (image_path.strip(".jpg") + "_colorless.jpg")
image_name = os.path.split(image_str)[1]
In the future I will put this into function above.

Related

getting "none" as result and don't uderstand why

I am learning how to program in python 3 and today i was praticing until i start to struggle with this.
I was trying to make a function to get to know the total square meters of wood that i'll use in one project, but i keep get the none result and i don't know why, even reading almost every post about it that i found here.
Anyway, here's the code:
from math import pi
def acirc(r):
pi*r**2
def madeiratotal(r1,r2,r3,r4,r5):
a = acirc(r1)
b = acirc(r2)
c = acirc(r3)
d = acirc(r4)
e = acirc(r5)
print (a+b+c+d+e)
madeiratotal(0.15,0.09,0.175,0.1,0.115)
I already try defining the "acirc" function inside the "madeiratotal" function, try to print all numbers separated and them suming then... I just don't know what else to do please help
You need to return value from acirc function otherwise return type is None
def acirc(r):
return pi*r**2

Godot 3.1 telling me that lock() and get_pixel() are nonexistent functions

I'm attempting to generate a height map from a noise texture. As far as I understand, in order to call get_pixel() on an image in this context, the image must first be locked. However, when I attempt to run the program, it exits with the error: Invalid call. Nonexistent function 'lock' in base 'StreamTexture'.
If I attempt to run it without locking the image, I get the error: Invalid call. Nonexistent function 'get_pixel' in base 'StreamTexture'.
I am certain that the instructions that I am following are for the same version of Godot I am running (3.1), so why is the engine telling me that lock() and get_pixel() are nonexistent functions?
My code is here:
extends Spatial
var width
var height
var heightData = {}
var vertices = PoolVector3Array()
var drawMesh = Mesh.new()
func _ready():
var noiseTexture = load("res://noiseTexture.png")
width = noiseTexture.get_width()
height = noiseTexture.get_height()
noiseTexture.lock()
for x in range(0, width):
for y in range(0, height):
heightData[Vector2(x,y)] = noiseTexture.get_pixel(x,y).r
noiseTexture.unlock()
for x in range(0, width-1):
for y in range(0, height-1):
createQuad(x,y)
var surfTool = SurfaceTool.new()
surfTool.begin(Mesh.PRIMITIVE_TRIANGLES)
for i in vertices.size():
surfTool.add_vertex(vertices[i])
surfTool.commit(drawMesh)
$MeshInstance.mesh = drawMesh
func createQuad(x,y):
#First half
vertices.push_back(Vector3(x, heightData[Vector2(x,y)], -y))
vertices.push_back(Vector3(x, heightData[Vector2(x,y+1)], -y-1))
vertices.push_back(Vector3(x+1, heightData[Vector2(x+1,y+1)], -y-1))
#Second Half
vertices.push_back(Vector3(x, heightData[Vector2(x,y)], -y))
vertices.push_back(Vector3(x+1, heightData[Vector2(x+1,y+1)], -y-1))
vertices.push_back(Vector3(x+1, heightData[Vector2(x+1,y)], -y))
Any help is greatly appreciated.
EDIT - I have (tried) to implement the changes that were suggested in the comments (yet I still don't know what to do with the color variable) and have attached a screenshot of my resulting code, as well as some comments I have made to try and explain to myself why the process SHOULD be working (I think). It also shows my node structure, which is why I opted to display this as an image. However, when I try to run this, the program crashes with the error displayed.
Check the docs;
StreamTexture does not have the method lock.
I think the class you are looking to use is Image. The Texture class is typically intended for drawing on the screen or applying to a Material
var noiseImage = Image.new()
noiseImage.load("res://noiseTexture.png")
noiseImage.lock() # Lock the image here
var color = noiseImage.get_pixel(10, 10) # Replace with your height map population
PS:
Just to let you know, I had a lot of issues with memory usage here so make sure you test that also (C# has bad garbage collector though).
You might need to dispose of the image, surface tool, and array mesh (If you remove the terrain object) to maintain optimum performance.
I have run into similar issues with generating heightmap terrains.
nathanfranke is correct and his solution will work.
If you for some reason use an ImageTexture you can call get_data() on that to get the underlying Image. Then you call lock() on the Image just like nathan says in his answer.
Take care to check that your coordinates for get_pixel() are correct. You can set a breakpoint by clicking on the very left edge of the line of code.
I mention this because I was very frustrated until I realized that my coordinate calculations were all int which resulted in the sampled pixel always being at <0,0>.
Here is part of my code for sampling an image into the HeightMapShape.map_data for Bullet heightmap collisions:
var map_w = shape.map_width
var map_h = shape.map_depth
var img_w = img.get_width()
var img_h = img.get_height()
img.lock()
for y in range(0, map_h):
py = float(img_h) * (float(y) / float(map_h))
for x in range(0, map_w):
px = float(img_w) * (float(x) / float(map_w))
index = y * img_h + x
pix = img.get_pixel(px, py)
shp.map_data[index] = pix.r * heightmap_height + heightmap_offset

opencv4nodejs how to use absdiff function

Prob a silly question but I cant find out how to use the absdiff() function in opencv4nodejs.
I have two Mats called reference and img and I want to see whats different on img from reference.
A code snippet is below
let reference = await cv.imreadAsync(referencePath);
const img = await cv.imreadAsync(imagePath);
// Get the difference
const diff = img.absdiff(reference);
console.log('after absdiff');
// Write out the difference
await cv.imwriteAsync(outputPath, diff);
My node server crashes during the function so the log never prints out. Any ideas would be great thanks .
On a side note can someone with the rep create the opencv4nodejs tag
Found out what it was ill leave this here if someone runs into the same issue!
So the images must be the same size for some reason my reference img was 2050*1520(or something like that) and my img was 1920*1080 both images must be the same size.

Finding Hyperlinks in Python 3

So my assignment is to write a program that reads all data from a web page and prints all hyperlinks of the form:
link text
So far I've gotten this far with the help of my instructor.
from urllib.request import urlopen
def findTitle(webpage):
encoding = "utf-8"
for webpagestr in webpage:
webpagestr = str(webpagestr,encoding)
if "<title>" in webpagestr:
indexstart = webpagestr.find("<title>")
indexend = webpagestr.find("</title>")
title = webpagestr[indexstart+7:indexend]
return title
return title
def H1headings(webpage):
encoding = "utf-8"
for webpagestr in webpage:
webpagestr = str(webpagestr,encoding)
if "<h1>" in webpagestr:
indexstart = webpagestr.find("<h1>")
indexend = webpagestr.find("</h1>")
heading = webpagestr[indexstart+4:indexend]
print(heading)
def main():
address = input("Enter URL to find title and more information: ")
try:
webpage = urlopen(address)
title = findTitle(webpage)
print("Title is", title)
H1headings(webpage)
webpage.close()
except Exception as exceptObj:
print("Error: ", str(exceptObj))
main()
When I run this program it allows me to input a URL but after it gives me a:
Error: local variable 'title' referenced before assignment
I'm not sure what it means.
Then one of my attempts when I placed:
def findTitle(webpage):
title = "Not Found"
encoding = "utf-8"
ran the program, it would give me:
Enter URL to find title and more information: http://jeremycowart.com
Title is not found
Jeremy Cowart
It's what I'm looking for, but I believe I'm suppose to have the title and heading as well as link text.
I've gotten close but I just can't figure it out. Any help would be appreciated!
There are at least a couple problems I see.
In your function findTitle, you always return the variable title, even if you haven't found one, and therefore haven't set the variable title to anything, hence when it fails to find a title on the web page (whether because there isn't one or your code failed to find it) it's returning a variable that hasn't been created/assigned yet.
First, you should fix your code so it doesn't do that. You can either change the final return statement to return a default value, e.g. "Not found" or you can set title to the default value at the top of your function, which guarantees it will exist no matter when it is returned, e.g.:
def foo(x):
y = -1
<do stuff, maybe re-setting y>
return y
That is the pattern I tend to prefer.
There is another problem though, which is preventing you from properly detecting the title. If you step through your program you should see it. Essentially, you start looping, get the first line, check to see if it has a title; if it does you return it (good), if it doesn't you skip the if, but then you return it anyway (not so good) and you never get to the second line.

Python load timer [duplicate]

So I have a .gif picture on a canvas in tkinter. I want this picture to change to another picture...but only for 3 seconds. and for it revert back to the original picture.
def startTurn(self):
newgif = PhotoImage(file = '2h.gif')
self.__leftImageCanvas.itemconfigure(self.__leftImage, image = newgif)
self.__leftImageCanvas.image = newgif
while self.cardTimer > 0:
time.sleep(1)
self.cardTimer -=1
oldgif = PhotoImage(file = 'b.gif')
self.__leftImageCanvas.itemconfigure(self.__leftImage, image = oldgif)
self.__leftImageCanvas.image = oldgif
this is a first attempt after a quick view of the timer. i know that this code does not make sense, but before i keep mindlessly trying to figure it out, i would much rather have more experienced input.
Tkinter widgets have a method named after which can be used to run a function after a specified period of time. To create an image and then change it three seconds later, you would do something like this:
def setImage(self, filename):
image = PhotoImage(file=filename)
self.__leftImageCanvas.itemconfigure(self.__leftImage, image=image)
self.__leftImageCanvas.image = image
def startTurn(self):
'''Set the image to "2h.gif", then change it to "b.gif" 3 seconds later'''
setImage("2h.gif")
self.after(3000, lambda: self.setImage("b.gif"))

Resources