OpenCV: bagaimana cara memaksa jendela gambar muncul di atas jendela lain?

Menggunakan cvShowImage, seseorang dapat dengan mudah menampilkan gambar di OpenCV. Namun, bagaimana Anda memberitahu OpenCV untuk menampilkan jendela di atas setiap jendela lainnya?

Saya menjalankan aplikasi OpenGL layar penuh sambil menampilkan gambar. Pertama kali jendela OpenCV muncul di atas jendela aplikasi saya, tetapi jika saya mengklik jendela aplikasi saya (yaitu mengembalikan fokus ke sana), maka saya tidak dapat mengatur agar OpenCV kembali ke atas. Jendela OpenGL, bahkan ketika menghancurkan dan membuat ulang jendela tersebut.

Saya berpikir untuk mengganti nama jendela setiap kali, tetapi apakah ada cara lain untuk melakukannya?


person seb    schedule 07.12.2011    source sumber
comment
Aplikasi openGL ini berjalan di layar penuh atau di jendela? Saya terpecah antara aplikasi openGL layar penuh dan mengklik jendela aplikasi   -  person Marcin Deptuła    schedule 07.12.2011
comment
Anda benar, ini tidak jelas: aplikasi OpenGL mengambil seluruh layar tetapi tidak diluncurkan dalam mode layar penuh; apakah ini mengubah sesuatu?   -  person seb    schedule 07.12.2011
comment
Memang benar. Ditambahkan ke jawaban karl. Saat Anda menguasai cvGetHandle, Anda dapat menggunakan windows sebagai di atas, atau menyetel jendela opengl sebagai induk dari gambar cv dengan fungsi SetParent(), dengan cara ini, ketika jendela induk Anda (openGL) aktif, jendela anak akan tetap terlihat tapi tidak aktif, itulah yang Anda inginkan.   -  person Marcin Deptuła    schedule 07.12.2011
comment
Anda akan lebih baik memasukkan objek OpenCV Mat ke dalam GUI Qt (menggunakan metode statis QImage atau QPixmap), maka GUI Qt akan memberi Anda kendali penuh.   -  person msmith81886    schedule 21.03.2018


Jawaban (8)


OpenCV tidak memiliki cara asli untuk melakukan ini (yang saya ketahui).

Jawabannya bergantung pada platform. Jika target Anda adalah Windows, periksa jawaban ini lalu ini dan ini tentu akan bermanfaat.

Jika Anda menggunakan Linux, Anda perlu melihat bagaimana OpenCV dikompilasi dan memeriksa sistem apa yang digunakannya (mungkin GTK+ 2.x). Kemudian, lakukan riset sendiri.

person karlphillip    schedule 07.12.2011
comment
Mungkin sesuatu yang lebih dari sekedar melakukan penelitian sendiri akan membantu. - person Kalev Maricq; 25.01.2020
comment
@KalevMaricq Pertanyaannya tidak jelas dalam hal platform target. Saya menawarkan sumber daya eksternal yang akan membantunya mencapai apa yang ingin dia lakukan di Windows, oleh karena itu tanda centang Jawaban Resmi. Pada saat itu (8 tahun yang lalu), jika Anda ingin melakukan ini di platform lain, diperlukan penelitian tambahan untuk mendapatkan jawabannya karena Stackoverflow tidak memiliki 20% jawaban yang dimiliki saat ini. Jangan ragu untuk memilih jawaban ini, memilih jawaban orang lain, atau menambahkan jawaban Anda sendiri yang mencakup cara melakukan ini di semua platform yang mendukung OpenCV. Itu akan sangat keren. - person karlphillip; 25.01.2020
comment
Bruce Christensen menjawab di bawah, bahwa ada properti WND_PROP_TOPMOST: cv2.setWindowProperty(window_name, cv2.WND_PROP_TOPMOST, 1) Berfungsi dengan baik hanya dengan OpenCV... - person Walchy; 15.03.2021
comment
NB: Pada rilis OpenCV 3.4.8/4.1.2 jawaban ini tidak lagi akurat (Saat itulah WND_PROP_TOPMOST ditambahkan). - person Dan Mašek; 14.06.2021
comment
@ DanMašek Jangan ragu untuk menambahkan komentar Anda sebagai jawaban. - person karlphillip; 14.06.2021

Oke, saya menemukan yang mana yang berfungsi untuk OSX dan Windows. Anda hanya perlu membuat jendela layar penuh dan menampilkannya dalam waktu yang sangat singkat, maka jendela berikutnya dari OpenCV akan muncul di depan. Jadi, pertama-tama buka jendela layar penuh:

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");

Dan kemudian Anda dapat membuka jendela lain yang benar-benar menampilkan gambar:

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

Ini berhasil untuk saya.

person xczhang    schedule 10.08.2017
comment
berfungsi untuk saya juga, di OSX El Capitan 10.11.6 dengan OpenCV 3.3.0_3 - person VisorZ; 02.10.2017
comment
Ini berfungsi OSX High Sierra. Namun menggunakan Python 2 Anda harus mengonversi 'cv::' dan 'CV_'* di atas menjadi 'cv2.' dan kemudian akan dikompilasi. Ini bukan peretasan yang bagus karena UX-nya buruk, tetapi untuk kode peretasan, itu sudah cukup. - person jeffg; 07.03.2018

Dimulai dengan OpenCV rilis 3.4.8 dan 4.1.2, setWindowProperty< /a> memiliki properti WND_PROP_TOPMOST yang dapat Anda gunakan mengatur. Contoh kode Python:

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
Berhasil! Ini harus menjadi jawaban teratas - person Walchy; 15.03.2021
comment
Memang benar, saya tidak tahu apakah ini berfungsi pada semua platform tetapi saya memverifikasi bahwa ini berfungsi pada MacOS (Big Sur). - person blackjack75; 30.03.2021
comment
Sekarang saya dapat memunculkan jendela di latar depan. Tetapi bagaimana cara mengizinkan jendela lain untuk ditampilkan nanti? Menyetel properti kembali ke 0 tidak mengizinkan hal ini. - person P i; 21.04.2021
comment
Terverifikasi berfungsi dengan backend Windows HighGUI biasa. - person Dan Mašek; 14.06.2021

Pada MAC-OSX (El Capitan) OpenCV 3.1.0, memanggil moveWindow sepertinya membawa jendela baru saja dipindahkan ke atas.

person PolarBear2015    schedule 31.10.2016
comment
moveWindow tidak memiliki efek seperti itu pada OpenCV 3.2.0 di Mac OS X Sierra. Jendela masih terbuka di bawah. - person sh37211; 04.07.2017
comment
Masalah yang sama dengan OCV 3.4 di 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' ''')

Menambahkan ini sebelum kode saya berfungsi untuk saya. Python 3.6.6 & macOS Mojave 10.14.2

Namun berhati-hatilah, gambar tersebut akan muncul di salah satu "Desktop" Anda dan bukan di layar Aplikasi Jendela yang Dimaksimalkan (saat Anda menekan tombol hijau di kiri atas aplikasi Anda)

person Alex    schedule 04.02.2019
comment
Ini berfungsi untuk saya di macOS Mojave, tetapi catatan bahwa saya harus memasukkan kode os.system('''/usr/bin/osascript -e 'tell app "Finder" to set frontmost of process "Python" to true' ''') setelah saya menelepon namedWindow - person Will Nathan; 29.08.2019

Solusi saya untuk OSX adalah memodifikasi kode OpenCV saya (versi 2.4.8), khususnya file windows_cocoa.mm di direktori highgui/src.

Jika Anda hanya ingin menampilkan jendela baru tanpa membuatnya aktif, tambahkan baris berikut tepat sebelum akhir fungsi cvNamedWindow() di windows_cocoa.mm:

[window orderFrontRegardless];

Untuk memaksa jendela baru agar selalu aktif, tambahkan baris berikut:

[application activateIgnoringOtherApps:YES];

Ini mungkin bukan ide terbaik untuk semua jendela tetapi berfungsi dalam situasi saya. Saya bosan harus selalu menampilkannya ke depan dengan mengkliknya untuk mengaktifkannya.

person bjeepka    schedule 21.03.2018

Saya menemukan solusi terbaik yang diposting di komentar di sini: Python OpenCV buka jendela di atas aplikasi lain

Cukup tambahkan perintah di bawah ini setelah membuka jendela, mis.

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

Gunakan "python" dalam huruf kecil. Menggunakan "Python", seperti yang saya temukan di beberapa jawaban, memberi saya kesalahan:

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

Awalnya saya mencoba mengedit file windows_cocoa.mm seperti yang disarankan di atas, tetapi tidak ada di komputer saya. Saya menggunakan mac osx mojave, OpenCV 3.4.2.

person Tauana Junqueira Cunha    schedule 04.01.2019
comment
Hanya berlaku untuk Mac-OSX. Ini berfungsi tetapi selalu setelah penundaan ~ 30 detik - person ishahak; 20.08.2019

Saya menemukan bahwa yang perlu saya lakukan hanyalah mengatur jendela utama saya ke layar penuh lalu kembali normal. Saya tidak perlu membuka jendela terpisah. Saya tidak perlu menampilkan gambar tiruan. Saya tidak perlu menelepon 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