Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cv.imshow not working in Mac #412

Open
iamlaobie opened this issue Sep 18, 2018 · 14 comments
Open

cv.imshow not working in Mac #412

iamlaobie opened this issue Sep 18, 2018 · 14 comments

Comments

@iamlaobie
Copy link

iamlaobie commented Sep 18, 2018

HI:
Thank you binding opencv for node!
I try the code in Mac,but the "cv.imshowWait" don't display the image,just hold the process.

(async () => {
  const img = await cv.imreadAsync('./faces/qiqi-1.jpg')
  console.log(img)
  cv.imshowWait('face detection', img);
})()
@justadudewhohacks
Copy link
Owner

What's your os? If you are not running on windows, did you compile OpenCV with libgtk or similar on Mac? Not sure why it simply hangs on your machine.

@vorg
Copy link

vorg commented Sep 20, 2018

Same here on MacOS 10.13.6 (17G65) after installing with npm i opencv4nodejs

@vcfvct
Copy link

vcfvct commented Oct 13, 2018

Same here, I was trying to run the typescript example faceRecognition0.ts. The execution stops at the cv.imshowWait. The node process just hanging with one image showing there, the subsequence cv.destroyAllWindows() never get a chance to execute.

I am on MacOS High Sierra. MBP2017 15", nodejs 8.11.x, typescript 3.x, ts-node 7.0.x and vscode 1.28.1.

Thanks.

@backcopy
Copy link

I can confirm it's a MacOS bug.

The event loop will block entirely until the spawned image process (or window, unsure how it's created) by imshowWait() receives user input, upon receiving input the event loop continues and everything resumes. Likely an issue upstream with the imshowWait() implementation.

@jmbldwn
Copy link

jmbldwn commented Apr 13, 2019

Did you find a workaround? I can't get cv.imshow() to work at all (no window appears). cv.imshowWait() displays a window with the image but of course it needs input before it will release the process.

@jmbldwn
Copy link

jmbldwn commented Apr 13, 2019

BTW, I think I have a workaround. I added cc::waitKey(1) after calling cv::imshow(). This appears to allow the window to show and be updated, but does not wait for a keypress:

The source I modified is in node_modules/opencv4nodejs/cc/modules/io/io.cc

NAN_METHOD(Io::Imshow) {
  FF_METHOD_CONTEXT("Imshow");
  if (!info[0]->IsString()) {
    FF_THROW("expected arg0 to be the window name");
  }
  if (!FF_IS_INSTANCE(Mat::constructor, info[1])) {
    FF_THROW("expected arg1 to be an instance of Mat");
  }
  cv::imshow(FF_CAST_STRING(info[0]), FF_UNWRAP_MAT_AND_GET(info[1]->ToObject(Nan::GetCurrentContext()).ToLocalChecked()));
  cv::waitKey(1);
}

@Garfonso
Copy link
Contributor

opencv (or better highgui) does all window handling in cv::waitKey. So waitKey is necessary to get your windows to do anything.
Why are you doing this in the c++ part? Why not call cv.waitKey(1) from javascript? Issue with your fix is that the cv::waitKey(1) might swallow keys that a user might want to process with cv.waitKey in javascript.

@jmbldwn
Copy link

jmbldwn commented Jul 28, 2019

@Garfonso Odd that none of the opencv examples indicated you need to call waitKey after imshow. Should the node binding require waitKey when other bindings don't?

@Garfonso
Copy link
Contributor

Garfonso commented Jul 28, 2019

@jmbldwn
The opencv examples usually call cv::waitKey() somewhere, at least the ones that I know. The documentation says quite clearly that you need to call cv::waitKey() to get the UI working:
https://docs.opencv.org/4.1.1/d7/dfc/group__highgui.html#ga5628525ad33f52eab17feebcfba38bd7

This function is the only method in HighGUI that can fetch and handle events, so it needs to be called periodically for normal event processing unless HighGUI is used within an environment that takes care of event processing.

The examples for opencv4nodejs usually call imshowWait which is a opencv4nodejs specific method and calls cv::waitKey(), as you can see here:

cv::waitKey();

it calls cv::waitKey without an argument, so waitKey will wait indefinitely for a key press. Usually that should make the window work fine. Of course the JS thread will be blocked until you press a key on the highgui window.

Also I do not know about what other bindings you are talking, tbh. But maybe they do not use opencv highgui but another UI?

@karthikvishwanath96
Copy link

karthikvishwanath96 commented Oct 19, 2019

I am sorry, but I am not able to grasp the concept. How am I actually supposed to call the waitKey function then? I am trying to play a video file using Electron js. I am using imshow to display the video in the window, and only one frame renders; until and unless I press any key on the keyboard. Then it would render the second frame and so on.. code for reference. (Does electron render in a highgui window? @Garfonso )
`
const videoLoad = new cv.VideoCapture(arg[0])

while(totalNumberofFrames) {

var readFrame = videoLoad.read();
var videoGray = readFrame.bgrToGray();
cv.imshow('video', videoGray)
cv.waitKey()

}
`

@Garfonso
Copy link
Contributor

I don't know what electron js is, but your code does look a lot like highgui.

Just add a parameter to the cv.waitKey().

cv.waitKey(n) waits n milliseconds for a keypress, so it returns after a key pressed or at least after n milliseconds. If the parameter is omitted, then it only returns when a key is pressed.
So you could calculate the wait time based on the fps of your video.

@karthikvishwanath96
Copy link

God damn, thanks! The problem was I only tried 0 as the 'n' value, just like in Python, and for some reason it does not work in opencv4nodejs the same way. It just stops at the first frame. I changed the n value to 1, now it renders all the frames. Thanks for the heads up! @Garfonso

@mlconnor
Copy link

mlconnor commented Jan 9, 2020

I'm hoping I can get this to work for me, I'm soooo close. I'm having the same/similar issue. Builds just fine and runs non-UI cv functions just fine. But when I use cv imshow it fails with the following. This is pretty obscure, I only found this error in a few items after Google searching. MacOS 10.14.6. opencv4nodejs 5.5.0. I used the (npm install opencv-build) to build. Any thoughts would be greatly appreciated. Also, the xmodules property on cv wasn't there so I had to change it to modules. Thanks in advance for anyone willing to give this a look.

const cv = require('opencv4nodejs');
const img = cv.imread('./data/husky.jpg')
console.log(img)
cv.imshow('face detection', img); // if I take this out, it runs normally. but doesn't show the img of course
cv.waitKey(5000);

And here is the test I was running...

Mat {
  step: 582,
  elemSize: 3,
  sizes: [ 259, 194 ],
  empty: 0,
  depth: 0,
  dims: 2,
  channels: 3,
  type: 16,
  cols: 194,
  rows: 259
}
 2020-01-09 18:17:44.285 node[57039:3405642] In -[NSApplication(NSQuietSafeQuit) _updateCanQuitQuietlyAndSafely], _LSSetApplicationInformationItem(NSCanQuitQuietlyAndSafely) returned error -50

@Maximvdw
Copy link

I am also facing the issue above with the exact same NSApplication error on macOS 10.15.5

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants