OpenCV: จะบังคับให้หน้าต่างรูปภาพปรากฏที่ด้านบนของหน้าต่างอื่นได้อย่างไร

การใช้ cvShowImage ทำให้สามารถแสดงรูปภาพใน OpenCV ได้อย่างง่ายดาย อย่างไรก็ตาม คุณจะบอก OpenCV ให้แสดงหน้าต่างที่ด้านบนของหน้าต่างอื่น ๆ ได้อย่างไร

ฉันเรียกใช้แอปพลิเคชัน OpenGL แบบเต็มหน้าจอขณะแสดงรูปภาพ ครั้งแรกที่หน้าต่าง OpenCV ปรากฏขึ้นที่ด้านบนของหน้าต่างแอปพลิเคชันของฉัน แต่หากฉันคลิกที่หน้าต่างแอปพลิเคชันของฉัน (เช่น ให้โฟกัสกลับไปที่หน้าต่างนั้น) ฉันก็จะไม่สามารถจัดการเพื่อให้ OpenCV กลับมาอยู่ด้านบนของ หน้าต่าง OpenGL แม้ว่าจะทำลายและสร้างหน้าต่างใหม่ก็ตาม

ฉันคิดจะเปลี่ยนชื่อหน้าต่างทุกครั้ง แต่มีวิธีอื่นอีกไหม


person seb    schedule 07.12.2011    source แหล่งที่มา
comment
แอปพลิเคชัน openGL นี้ทำงานแบบเต็มหน้าจอหรือในหน้าต่าง ฉันขาดระหว่างแอป openGL แบบเต็มหน้าจอและคลิกบนหน้าต่างแอปพลิเคชัน   -  person Marcin Deptuła    schedule 07.12.2011
comment
คุณพูดถูก มันไม่ชัดเจน: แอปพลิเคชัน OpenGL ใช้เวลาทั้งหน้าจอ แต่ไม่ได้เปิดใช้งานในโหมดเต็มหน้าจอ สิ่งนี้เปลี่ยนแปลงอะไรบางอย่างหรือเปล่า?   -  person seb    schedule 07.12.2011
comment
มันทำ เพิ่มในคำตอบของคาร์ล เมื่อคุณได้รับการจัดการด้วย cvGetHandle คุณสามารถเปิดหน้าต่างเป็นแบบด้านบน หรือตั้งค่าหน้าต่าง opengl เป็นพาเรนต์ของอิมเมจ cv ด้วยฟังก์ชัน SetParent() ด้วยวิธีนี้ เมื่อหน้าต่างพาเรนต์ของคุณ (openGL) จะทำงาน หน้าต่างลูกจะยังคงมองเห็นได้ แต่ไม่แอคทีฟซึ่งเป็นสิ่งที่คุณต้องการ   -  person Marcin Deptuła    schedule 07.12.2011
comment
คุณควรป้อนวัตถุ OpenCV Mat ลงใน Qt GUI จะดีกว่า (โดยใช้วิธีคงที่ QImage หรือ QPixmap) จากนั้น Qt GUI จะให้การควบคุมทั้งหมดแก่คุณ   -  person msmith81886    schedule 21.03.2018


คำตอบ (8)


OpenCV ไม่มีวิธีดั้งเดิมในการทำเช่นนี้ (ที่ฉันทราบ)

คำตอบนั้นขึ้นอยู่กับแพลตฟอร์ม หากเป้าหมายของคุณคือ Windows ให้ตรวจสอบคำตอบนี้ จากนั้นจึงเลือก สิ่งนี้และสิ่งนี้จะมีประโยชน์อย่างแน่นอน

หากคุณใช้ Linux คุณต้องดูวิธีการคอมไพล์ OpenCV และตรวจสอบว่าระบบใดที่สร้างขึ้น (อาจเป็น GTK+ 2.x) จากนั้นให้ทำการวิจัยของคุณเอง

person karlphillip    schedule 07.12.2011
comment
บางทีอะไรที่มากกว่าการค้นคว้าด้วยตัวเองอาจจะเป็นประโยชน์ก็ได้ - person Kalev Maricq; 25.01.2020
comment
@KalevMaricq คำถามนั้นคลุมเครือในแง่ของแพลตฟอร์มเป้าหมาย ฉันเสนอแหล่งข้อมูลภายนอกที่จะช่วยให้เขาบรรลุสิ่งที่ต้องการทำบน Windows จึงมีเครื่องหมายถูกคำตอบอย่างเป็นทางการ ในเวลานั้น (8 ปีที่แล้ว) หากคุณต้องการทำสิ่งนี้ในแพลตฟอร์มอื่นๆ จำเป็นต้องมีการวิจัยเพิ่มเติมเพื่อให้ได้คำตอบ เนื่องจาก Stackoverflow ไม่มีคำตอบถึง 20% ที่มีอยู่ในปัจจุบัน อย่าลังเลที่จะโหวตคำตอบนี้ โหวตให้คนอื่น หรือเพิ่มคำตอบของคุณเองซึ่งครอบคลุมวิธีการทำสิ่งนี้ในทุกแพลตฟอร์มที่รองรับ OpenCV นั่นคงจะเจ๋งทีเดียว - person karlphillip; 25.01.2020
comment
Bruce Christensen ตอบด้านล่างว่ามีคุณสมบัติ WND_PROP_TOPMOST: cv2.setWindowProperty(window_name, cv2.WND_PROP_TOPMOST, 1) ทำงานได้ดีกับ OpenCV เท่านั้น... - person Walchy; 15.03.2021
comment
หมายเหตุ: ตั้งแต่ OpenCV เปิดตัว 3.4.8/4.1.2 คำตอบนี้ไม่ถูกต้องอีกต่อไป (นั่นคือตอนที่ WND_PROP_TOPMOST ถูกเพิ่ม) - person Dan Mašek; 14.06.2021
comment
@ DanMašek อย่าลังเลที่จะเพิ่มความคิดเห็นของคุณเป็นคำตอบ - person karlphillip; 14.06.2021

ตกลง ฉันคิดแล้วว่าอันไหนใช้ได้กับทั้ง OSX และ Windows คุณเพียงแค่ต้องสร้างหน้าต่างแบบเต็มหน้าจอและแสดงหน้าต่างนั้นในระยะเวลาอันสั้น จากนั้นหน้าต่างถัดไปจาก OpenCV จะอยู่ข้างหน้า ดังนั้นก่อนอื่นให้เปิดหน้าต่างแบบเต็มหน้าจอ:

cv::namedWindow("GetFocus", CV_WINDOW_NORMAL);
cv::Mat img = cv::Mat::zeros(100, 100, CV_8UC3);
cv::imshow("GetFocus", img);
cv::setWindowProperty("GetFocus", CV_WND_PROP_FULLSCREEN, CV_WINDOW_FULLSCREEN);
waitKey(1);
cv::setWindowProperty("GetFocus", CV_WND_PROP_FULLSCREEN, CV_WINDOW_NORMAL);
destroyWindow("GetFocus");

จากนั้นคุณสามารถเปิดหน้าต่างอื่นที่แสดงภาพได้จริง:

Mat your_image = ...;
cv::namedWindow("ShowImg");
cv::imshow("ShowImg", your_image);

มันได้ผลสำหรับฉัน

person xczhang    schedule 10.08.2017
comment
ใช้ได้กับฉันเช่นกันบน OSX El Capitan 10.11.6 พร้อม OpenCV 3.3.0_3 - person VisorZ; 02.10.2017
comment
สิ่งนี้ใช้ได้กับ OSX High Sierra ใช้ Python 2 แม้ว่าคุณจะต้องแปลง 'cv::' และ 'CV_'* ด้านบนเป็น 'cv2' แล้วมันก็จะคอมไพล์ มันไม่ใช่แฮ็คที่ยอดเยี่ยมเพราะ UX นั้นแย่ แต่สำหรับโค้ดที่ถูกแฮ็กก็เพียงพอแล้ว - person jeffg; 07.03.2018

เริ่มต้นด้วย OpenCV รุ่น 3.4.8 และ 4.1.2 setWindowProperty< /a> มีคุณสมบัติ WND_PROP_TOPMOST คุณสมบัติที่คุณสามารถทำได้ ชุด. ตัวอย่างรหัสหลาม:

import cv2
import numpy as np

window_name = "image"
img = np.zeros([480, 640, 1])
cv2.imshow(window_name, img)
cv2.setWindowProperty(window_name, cv2.WND_PROP_TOPMOST, 1)
cv2.waitKey(0)
person Bruce Christensen    schedule 25.02.2021
comment
ได้ผล! นี่ควรเป็นคำตอบยอดนิยม - person Walchy; 15.03.2021
comment
อันที่จริงฉันไม่รู้ว่าสิ่งนี้ใช้ได้กับทุกแพลตฟอร์มหรือไม่ แต่ฉันตรวจสอบแล้วว่าใช้งานได้บน MacOS (Big Sur) - person blackjack75; 30.03.2021
comment
ตอนนี้ฉันสามารถวางไข่ในเบื้องหน้าได้แล้ว แต่จะอนุญาตให้หน้าต่างอื่นแสดงทับในภายหลังได้อย่างไร การตั้งค่าคุณสมบัติกลับเป็น 0 ไม่อนุญาตให้ทำเช่นนี้ - person P i; 21.04.2021
comment
ตรวจสอบแล้วว่าใช้งานได้กับแบ็กเอนด์ Windows HighGUI ปกติ - person Dan Mašek; 14.06.2021

บน MAC-OSX (El Capitan) OpenCV 3.1.0 การเรียก moveWindow ดูเหมือนว่าจะนำหน้าต่างที่เพิ่งย้ายไปด้านบน

person PolarBear2015    schedule 31.10.2016
comment
moveWindow ไม่มีผลกระทบดังกล่าวภายใต้ OpenCV 3.2.0 บน Mac OS X Sierra หน้าต่างยังคงเปิดอยู่ด้านล่าง - person sh37211; 04.07.2017
comment
ปัญหาเดียวกันกับ OCV 3.4 บน Mac 10.11 - person Mike Mitterer; 19.01.2018

import os os.system('''/usr/bin/osascript -e 'tell app "Finder" to set frontmost of process "Python" to true' ''')

เพิ่มสิ่งนี้ก่อนที่รหัสใด ๆ ของฉันจะได้ผลสำหรับฉัน Python 3.6.6 และ macOS Mojave 10.14.2

แต่ระวังด้วย รูปภาพนั้นจะปรากฏขึ้นบนหนึ่งใน "เดสก์ท็อป" ของคุณ และไม่อยู่ในหน้าจอแอปขยายหน้าต่างใหญ่สุด (เมื่อคุณกดปุ่มสีเขียวที่ด้านซ้ายบนของแอป)

person Alex    schedule 04.02.2019
comment
สิ่งนี้ใช้ได้กับฉันใน macOS Mojave แต่มีหมายเหตุว่าฉันต้องใส่รหัส os.system('''/usr/bin/osascript -e 'tell app "Finder" to set frontmost of process "Python" to true' ''') หลังจากที่ฉันโทร namedWindow - person Will Nathan; 29.08.2019

โซลูชันของฉันสำหรับ OSX คือการแก้ไขโค้ด OpenCV ของฉัน (เวอร์ชัน 2.4.8) โดยเฉพาะไฟล์ windows_cocoa.mm ในไดเรกทอรี highgui/src

หากคุณต้องการนำหน้าต่างใหม่มาไว้ด้านหน้าโดยไม่ทำให้หน้าต่างแอ็คทีฟ ให้เพิ่มบรรทัดต่อไปนี้ก่อนสิ้นสุดฟังก์ชัน cvNamedWindow() ใน windows_cocoa.mm:

[window orderFrontRegardless];

หากต้องการบังคับให้หน้าต่างใหม่เปิดใช้งานอยู่เสมอ ให้เพิ่มบรรทัดต่อไปนี้แทน:

[application activateIgnoringOtherApps:YES];

อาจไม่ใช่ความคิดที่ดีที่สุดสำหรับ windows ทั้งหมด แต่ใช้ได้ผลในสถานการณ์ของฉัน ฉันเบื่อที่ต้องนำพวกมันมาไว้ด้านหน้าโดยคลิกที่พวกมันเพื่อให้มันใช้งานได้

person bjeepka    schedule 21.03.2018

ฉันพบวิธีแก้ปัญหาที่ดีที่สุดที่โพสต์ในความคิดเห็นที่นี่: Python OpenCV เปิดหน้าต่างที่ด้านบนของแอปพลิเคชันอื่นๆ

เพียงเพิ่มคำสั่งด้านล่างหลังจากเปิดหน้าต่าง เช่น

cv2.namedWindow('img_file_name', cv2.WINDOW_NORMAL) # Creates a window
os.system('''/usr/bin/osascript -e 'tell app "Finder" to set frontmost of process "python" to true' ''') # To make window active

ใช้ "python" เป็นตัวพิมพ์เล็ก การใช้ "Python" อย่างที่ฉันพบในคำตอบบางข้อทำให้ฉันมีข้อผิดพลาด:

21:62: execution error: Finder got an error: Can’t set process "Python" to true. (-10006))

ตอนแรกฉันพยายามแก้ไขไฟล์ windows_cocoa.mm ตามที่แนะนำข้างต้น แต่ไม่มีอยู่ในคอมพิวเตอร์ของฉัน ฉันใช้ mac osx mojave, OpenCV 3.4.2

person Tauana Junqueira Cunha    schedule 04.01.2019
comment
ใช้ได้กับ Mac-OSX เท่านั้น มันใช้งานได้ แต่มักจะหลังจากล่าช้า ~ 30 วินาทีเสมอ - person ishahak; 20.08.2019

ฉันพบว่าสิ่งที่ฉันต้องทำคือตั้งค่าหน้าต่างหลักให้เต็มหน้าจอแล้วกลับมาเป็นปกติ ฉันไม่จำเป็นต้องเปิดหน้าต่างแยกต่างหาก ฉันไม่จำเป็นต้องแสดงภาพจำลอง ฉันไม่จำเป็นต้องโทรหา waitKey

    #!/usr/bin/env python
    import cv2
    import numpy

    WindowName="Main View"
    view_window = cv2.namedWindow(WindowName,cv2.WINDOW_NORMAL)

    # These two lines will force your "Main View" window to be on top with focus.
    cv2.setWindowProperty(WindowName,cv2.WND_PROP_FULLSCREEN,cv2.WINDOW_FULLSCREEN)
    cv2.setWindowProperty(WindowName,cv2.WND_PROP_FULLSCREEN,cv2.WINDOW_NORMAL)

    # The rest of this does not matter. This would be the rest of your program.
    # This just shows an image so that you can see that this example works.
    img = numpy.zeros((400,400,3), numpy.uint8)
    for x in range(0,401,100):
        for y in range(0,401,100):
            cv2.line(img,(x,0),(0,y),(128,128,254),1)
            cv2.line(img,(x,399),(0,y),(254,128,128),1)
            cv2.line(img,(399,y),(x,399),(128,254,128),1)
            cv2.line(img,(399,y),(x,0),(254,254,254),1)
    cv2.imshow(WindowName, img)
    cv2.waitKey(0)
    cv2.destroyWindow(WindowName)
person Noah Spurrier    schedule 27.03.2019