Skip to content

Commit

Permalink
Merge pull request #150 from EmixamPP/opencv_err
Browse files Browse the repository at this point in the history
Fix: Driver configured but not found & OpenCV exception on video feedback
  • Loading branch information
EmixamPP authored Nov 3, 2023
2 parents 912ff4e + 67fd929 commit 5efaae8
Show file tree
Hide file tree
Showing 10 changed files with 102 additions and 23 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Wed Nov 1 2023 - 5.2.4
- Fix driver generated but not found
- Fix for OpenCV exception thrown
- Reduction in installation size
# Fri Oct 20 2023 - 5.2.1
- Fix unable to execute commands
# Thu Oct 19 2023 - 5.2.0
Expand Down
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ We also support OpenRC, just download the `.openrc` variant.
It can be uninstalled by executing (remove the last line to keep the emitter configuration):
```
sudo rm -rf /usr/lib64/linux-enable-ir-emitter \
/usr/libexec/linux-enable-ir-emitter \
/usr/bin/linux-enable-ir-emitter \
/usr/lib/systemd/system/linux-enable-ir-emitter.service \
/etc/udev/rules.d/99-linux-enable-ir-emitter.rules \
Expand Down
79 changes: 65 additions & 14 deletions camera/camera.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ constexpr int NOK_KEY = 110;
*/
bool Camera::isGrayscale()
{
unique_ptr<cv::Mat> frame = read1();
auto frame = read1();

if (frame->channels() != 3)
return false;
Expand Down Expand Up @@ -163,8 +163,7 @@ void Camera::closeCap() noexcept
cap->release();
}

Camera::Camera(const string &device)
: id(Camera::deviceId(device)), device(device)
Camera::Camera(const string &device) : id(Camera::deviceId(device)), device(device)
{
cv::utils::logging::setLogLevel(cv::utils::logging::LogLevel::LOG_LEVEL_ERROR);
}
Expand Down Expand Up @@ -225,47 +224,94 @@ bool Camera::apply(const CameraInstruction &instruction)
*
* @return the frame
*/
unique_ptr<cv::Mat> Camera::read1()
shared_ptr<cv::Mat> Camera::read1()
{
openCap();
auto frame = make_unique<cv::Mat>();
auto frame = make_shared<cv::Mat>();
cap->read(*frame);
closeCap();
return frame;
}

/**
* @brief Check if the emitter is working
* by showing a video feedback and
* asking confirmation to the user
* @brief Show a video feedback to the user
* and asks if the emitter is working
*
* @throw CameraException if unable to open the camera device
*
* @return true if yes, false if not
*/
bool Camera::isEmitterWorking()
bool Camera::isEmitterWorkingAsk()
{
openCap();
cv::Mat frame;
int key = -1;

cout << "Is the video flashing? Press Y or N in the window" << endl;

while (key != OK_KEY && key != NOK_KEY)
{
cap->read(frame);
cv::imshow("linux-enable-ir-emitter", frame);
key = cv::waitKey(5);
}

cout << (key == OK_KEY ? "Y pressed" : "N pressed") << endl;

closeCap();
cv::destroyAllWindows();

return key == OK_KEY;
}

/**
* @brief Trigger the camera
* and asks if the emitter is working
*
* @throw CameraException if unable to open the camera device
*
* @return true if yes, false if not
*/
bool Camera::isEmitterWorkingAskNoGui()
{
cv::Mat frame;
cap->read(frame);

string answer;
cout << "Is the ir emitter flashing (not just turn on) ? Yes/No ? ";
cin >> answer;
transform(answer.begin(), answer.end(), answer.begin(), [](char c)
{ return tolower(c); });

while (answer != "yes" && answer != "y" && answer != "no" && answer != "n")
{
cout << "Yes/No ? ";
cin >> answer;
transform(answer.begin(), answer.end(), answer.begin(), [](char c)
{ return tolower(c); });
}

return answer == "yes" || answer == "y";
}

/**
* @brief Check if the emitter is working
* by asking confirmation to the user
*
* @throw CameraException if unable to open the camera device
*
* @return true if yes, false if not
*/
bool Camera::isEmitterWorking()
{
openCap();

bool res;
if (noGui)
res = isEmitterWorkingAskNoGui();
else
res = isEmitterWorkingAsk();

closeCap();

return res;
}

/**
* @brief Execute an uvc query on the device indicated by the file descriptor
*
Expand Down Expand Up @@ -388,6 +434,11 @@ uint16_t Camera::lenUvcQuery(uint8_t unit, uint8_t selector)
return len;
}

void Camera::disableGui()
{
noGui = true;
}

CameraException::CameraException(const string &device) : message("Cannot access to " + device) {}

const char *CameraException::what() const noexcept
Expand Down
9 changes: 8 additions & 1 deletion camera/camera.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class Camera
int id;
int fd = -1;
const shared_ptr<cv::VideoCapture> cap = make_shared<cv::VideoCapture>();
bool noGui = false;

protected:
int getFd() const noexcept;
Expand All @@ -36,6 +37,10 @@ class Camera

int executeUvcQuery(const uvc_xu_control_query &query);

bool isEmitterWorkingAsk();

bool isEmitterWorkingAskNoGui();

public:
const string device;

Expand All @@ -59,7 +64,7 @@ class Camera

virtual bool isEmitterWorking();

unique_ptr<cv::Mat> read1();
shared_ptr<cv::Mat> read1();

int setUvcQuery(uint8_t unit, uint8_t selector, vector<uint8_t> &control);

Expand All @@ -70,6 +75,8 @@ class Camera
bool isGrayscale();

static shared_ptr<Camera> findGrayscaleCamera();

void disableGui();
};

class CameraException : public exception
Expand Down
2 changes: 1 addition & 1 deletion command/commands.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ using namespace std;

extern "C"
{
ExitCode configure(const char* device, bool manual, unsigned emitters, unsigned negAnswerLimit);
ExitCode configure(const char* device, bool manual, unsigned emitters, unsigned negAnswerLimit, bool noGui);
ExitCode delete_driver(const char* device);
ExitCode run(const char* device);
ExitCode test(const char* device);
Expand Down
8 changes: 6 additions & 2 deletions command/configure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,11 @@ void enableDebug()
* @param manual true for enabling the manual configuration
* @param emitters number of emitters on the device
* @param negAnswerLimit number of negative answer before the pattern is skiped. Use -1 for unlimited
* @param noGui no gui video feedback
*
* @return exit code
*/
ExitCode configure(const char *device_char_p, bool manual, unsigned emitters, unsigned negAnswerLimit)
ExitCode configure(const char *device_char_p, bool manual, unsigned emitters, unsigned negAnswerLimit, bool noGui)
{
const string device = string(device_char_p);

Expand All @@ -49,12 +50,15 @@ ExitCode configure(const char *device_char_p, bool manual, unsigned emitters, un
camera = make_shared<AutoCamera>(device);
}

if (noGui)
camera->disableGui();

if (camera == nullptr)
Logger::critical(ExitCode::FAILURE, "Impossible to find an infrared camera.");

Logger::info("Configuring the camera:", camera->device, ".");

const string deviceName = device.substr(device.find_last_of("/") + 1);
const string deviceName = camera->device.substr(camera->device.find_last_of("/") + 1);
const string excludedPath = SAVE_DRIVER_FOLDER_PATH + deviceName + ".excluded";
Finder finder(*camera, emitters, negAnswerLimit, excludedPath);

Expand Down
1 change: 1 addition & 0 deletions command/load_cpp_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
ctypes.c_bool,
ctypes.c_uint32,
ctypes.c_uint32,
ctypes.c_bool,
]
cpp_commands.configure.restype = ctypes.c_int

Expand Down
15 changes: 14 additions & 1 deletion linux-enable-ir-emitter.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,13 @@
default=40,
type=int,
)
command_configure.add_argument(
"-g",
"--no-gui",
help="no gui video feedback",
action="store_true",
default=False,
)
command_test = command_subparser.add_parser(
"test",
help="test a camera",
Expand Down Expand Up @@ -119,7 +126,13 @@

elif args.command == "configure":
check_root()
res = cpp_commands.configure(device.encode(), args.manual, args.emitters, args.limit)
res = cpp_commands.configure(
device.encode(),
args.manual,
args.emitters,
args.limit,
args.no_gui
)
if res == ExitCode.SUCCESS:
boot("enable")

Expand Down
4 changes: 2 additions & 2 deletions meson.build
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
project(
'linux-enable-ir-emitter',
'cpp',
version: '5.2.1',
version: '5.2.3',
license: 'MIT',
default_options: [
'prefix=/usr',
'cpp_std=c++17',
'optimization=3',
'buildtype=release',
'warning_level=everything',
'werror=true',
],
Expand Down
2 changes: 1 addition & 1 deletion utils/globals.hpp.in
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#include <vector>
using namespace std;

const string SAVE_DRIVER_FOLDER_PATH = "@SAVE_DRIVER_FOLDER_PATH@";
const string SAVE_DRIVER_FOLDER_PATH = "@SAVE_DRIVER_FOLDER_PATH@/";

enum ExitCode
{
Expand Down

0 comments on commit 5efaae8

Please sign in to comment.