plt.plot(…)没有显示窗口。我错过了什么吗?

huangapple go评论71阅读模式
英文:

plt.plot(...) doesn't show a window. what am I missing?

问题

Here's the translated code portion:

我正在使用VScode进行OpenCV练习

我习惯于使用以下结构显示图像

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

    puppy = cv2.imread('./DATA/00-puppy.jpg')
    horse = cv2.imread('./DATA/horse.jpg')
    rainbow = cv2.imread('./DATA/rainbow.jpg')

    # 对这些图像进行“inplace”操作,例如
    # puppy = cv2.cvtColor(puppy, cv2.COLOR_BGR2RGB)
    # 等...

    img_to_show_1 = puppy
    img_to_show_2 = horse
    img_to_show_3 = rainbow

    # ---> 开始“while True ... - if 0xFF == 27: break”结构

    cv2.namedWindow(winname='window_1')
    cv2.namedWindow(winname='window_2')
    cv2.namedWindow(winname='window_3')

    while True:
        cv2.imshow('window_1', img_to_show_1)
        cv2.imshow('window_2', img_to_show_2)
        cv2.imshow('window_3', img_to_show_3)

        if cv2.waitKey(1) & 0xFF == 27: # 当按下'esc'键时停止循环
            break

    cv2.destroyAllWindows()

    # ---> 结束“while True ... - if 0xFF == 27: break”结构

现在我已计算存储在puppy变量中的图像的值的直方图

    hist_values = cv2.calcHist([puppy], channels=[0], mask=None, histSize=[256], ranges=[0,256])

在Jupyter笔记本上可以通过简单执行以下操作来显示它

    plt.plot(hist_values)

但在VScode上这不会显示任何内容

是否有一种方法可以在VScode上显示此图像而不需要安装任何其他图形扩展

是否有一种方法可以利用相同的while True ... - if 0xFF == 27: break结构以便在按下'esc'键时也使此图像消失就像其他图像一样

This is the translated code portion you requested.

英文:

I am practicing with open cv on VScode.

I am used to display images by using the following structure:

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

puppy = cv2.imread('./DATA/00-puppy.jpg')
horse = cv2.imread('./DATA/horse.jpg')
rainbow = cv2.imread('./DATA/rainbow.jpg')

# "inplace" operations on these images such as
# puppy = cv2.cvtColor(puppy, cv2.COLOR_BGR2RGB)
# etc...

img_to_show_1 = puppy
img_to_show_2 = horse
img_to_show_3 = rainbow

# ---> beginning of the "while True ... - if 0xFF == 27: break" structure

cv2.namedWindow(winname='window_1')
cv2.namedWindow(winname='window_2')
cv2.namedWindow(winname='window_3')


while True:
	cv2.imshow('window_1', img_to_show_1)
	cv2.imshow('window_2', img_to_show_2)    
	cv2.imshow('window_3', img_to_show_3)

	if cv2.waitKey(1) & 0xFF == 27: # stop loop when 'esc' key is pressed
		break

cv2.destroyAllWindows()

# ---> end of the "while True ... - if 0xFF == 27: break" structure

Now I have calculated the histogram of the values of an image stored in puppy variable

hist_values = cv2.calcHist([puppy], channels=[0], mask=None, histSize=[256], ranges=[0,256])

On jupyter notebooks, this can be showed by simply doing:

plt.plot(hist_values)

But on VScode, this does not show anything.

Is there a way to show this image on VScode and without intalling any other graphical extention?

Is there a way to exploit the same "while True ... - if 0xFF == 27: break" structure, in order to have this image also disappear with the others as I press 'esc' key?

答案1

得分: 0

我找到了一个解决方法。

这基于使用OpenCV模块方法保存图像,然后使用Matplotlib方法重新加载图像:

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

puppy = cv2.imread('./DATA/00-puppy.jpg')
horse = cv2.imread('./DATA/horse.jpg')
rainbow = cv2.imread('./DATA/rainbow.jpg')

hist_values = cv2.calcHist([puppy], channels=[0], mask=None, histSize=[256], ranges=[0, 256])

plt.plot(hist_values)
plt.plot([1, 2])
mypath = 'my/path/hist_values.jpg'
plt.savefig(mypath)

hist_values_img = cv2.imread(mypath)

import os
try:
    os.remove(mypath)
except:
    print("无法删除{}".format(mypath))

img_to_show_1 = puppy
img_to_show_2 = hist_values_img
img_to_show_3 = rainbow

cv2.namedWindow(winname='window_1')
cv2.namedWindow(winname='window_2')
cv2.namedWindow(winname='window_3')

while True:
    cv2.imshow('window_1', img_to_show_1)
    cv2.imshow('window_2', img_to_show_2)
    cv2.imshow('window_3', img_to_show_3)
    plt.show()

    if cv2.waitKey(1) & 0xFF == 27:  # 如果按下esc键
        break

cv2.destroyAllWindows()

通过这种方式,我没有混合GUI,并且当我按下'esc'键时,直方图图像会与其他图像一起关闭。

感谢@ChristophRackwitz。

另外,将Matplotlib格式的元素转换为OpenCV格式的元素的代码段可以缩短为以下函数:

def convert_matplotlib_to_opencv_img(matplotlib_format_img, clear=False, transitory_img_path='my_transitory_img.jpg'):

    if clear:
        plt.clf()

    plt.plot(matplotlib_format_img)

    try:
        plt.savefig(transitory_img_path)
    except:
        raise OSError("无法保存图像到{}".format(transitory_img_path))

    cv2_imread_format_img = cv2.imread(transitory_img_path)

    import os
    try:
        os.remove(transitory_img_path)
    except:
        print("无法删除{}".format(transitory_img_path))

    return cv2_imread_format_img

希望这对你有所帮助。

英文:

I found a workaround to do it.

This is based on saving the image with opencv module method and to reload it with the matplotlib method:

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

puppy = cv2.imread('./DATA/00-puppy.jpg')
horse = cv2.imread('./DATA/horse.jpg')
rainbow = cv2.imread('./DATA/rainbow.jpg')

# "inplace" operations on these images such as
# puppy = cv2.cvtColor(puppy, cv2.COLOR_BGR2RGB)
# etc...

hist_values = cv2.calcHist([puppy], channels=[0], mask=None, histSize=[256], ranges=[0,256])

plt.plot(hist_values)
plt.plot([1, 2])
mypath = 'my/path/hist_values.jpg'
plt.savefig(mypath)

hist_values_img = cv2.imread(mypath)

import os
try: 
    os.remove(hist_values_path)
except: 
    print("could not remove {}".format(hist_values_path))

img_to_show_1 = puppy
img_to_show_2 = hist_values_img
img_to_show_3 = rainbow

# ---> beginning of the "while True ... - if 0xFF == 27: break" structure

cv2.namedWindow(winname='window_1')
cv2.namedWindow(winname='window_2')
cv2.namedWindow(winname='window_3')

while True:
	cv2.imshow('window_1', img_to_show_1)
	cv2.imshow('window_2', img_to_show_2)    
	cv2.imshow('window_3', img_to_show_3)
	plt.show()

	if cv2.waitKey(1) & 0xFF == 27: # se premo esc
		break

cv2.destroyAllWindows()

# ---> end of the "while True ... - if 0xFF == 27: break" structure

In this way I am not mixing GUIs and as I press 'esc', the histogram image closes together with the other images.

Credits to @ChristophRackwitz

Also, the snippet to convert a matplotlib-format element to a opencv-format element can be shrinked to this function:

def convert_matplotlib_to_opencv_img(matplotlib_format_img, clear=False, transitory_img_path='my_transitory_img.jpg'):

	if clear:
		plt.clf()

	plt.plot(matplotlib_format_img)

	try:
		plt.savefig(transitory_img_path)
	except: 
		raise OSError("could not save img to {}".format(transitory_img_path))

	cv2_imread_format_img = cv2.imread(transitory_img_path)

	import os
	try: 
		os.remove(transitory_img_path)
	except: 
		print("could not remove {}".format(transitory_img_path))

	return cv2_imread_format_img

huangapple
  • 本文由 发表于 2023年6月18日 20:12:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/76500476.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定