Collection of IC4 examples.
All examples are released under the Apache 2.0 License.
IC4 Example Programs
License: Apache License 2.0
I am using the qt6-first-steps.py
file to start working with ic4, and I'm able to detect my device. But when the app starts I am only shown the first image taken and it's still, not live updating.
Hello TIS
We have been lent a VGA camera (DFK 23G 618) whilst waiting delivery of some 4K versions. This is causing me some problems. Questions arising:
static constexpr ic4::PixelFormat dev_format = ic4::PixelFormat::BGR8;
ok = map.setValue(ic4::PropId::PixelFormat, dev_format, err);
This image is rendering what I think is 24bpp data with dimensions of 640x480:
imageBuffer
(whatever its format) to Windows style BGR (24bpp) or BGRA (32bpp)? All I can find are the write to a bitmap file family.Thanks again for listening. Any advice much appreciated.
Hello.
Is the properties dialog running its own message loop in its own thread?
I ask as the minimal Win32 based example shown below will continue to allow update the incoming image as the various properties are modified without any problem.
But I've got one case where a DirectX9 based framework is in use and the properties dialog appears to block all messages whilst it is visible. This means modified property values are not visibly applied until the dialog is dismissed. Which is, of course, not what is required.
Any comments welcomed.
Many thanks.
Hi,
I'm trying to use grabber.stream_statistics to know if I'm missing frames, but I don't understand the results I'm getting from it.
Sometimes a frame is missed, and i get the following stats:
Grabber.StreamStatistics(device_delivered=1000, device_transmission_error=0, device_underrun=0, transform_delivered=0, transform_underrun=0, sink_delivered=999, sink_underrun=0, sink_ignored=0)
My question is : where is my missing frame if it doesnt appear in stats but has been delivered by device ? Did I miss something in the documentation?
Another question : device_delivered does not seem to be more than allocated buffers in sink. Why is that ?
All the best,
The following code reproduce the problem on my PC:
import sys
import time
import imagingcontrol4 as ic4
def sleep_ns(duration):
now = time.perf_counter_ns()
end = now + duration
while now < end:
now = time.perf_counter_ns()
class MyListener(ic4.QueueSinkListener):
def __init__(self):
pass
def sink_connected(self, sink: ic4.QueueSink, image_type: ic4.ImageType, min_buffers_required: int) -> bool:
# Just accept whatever is passed
sink.alloc_and_queue_buffers(2000)
return True
def sink_disconnected(self, sink: "QueueSink"):
print("Disconnected !!")
def frames_queued(self, sink: ic4.QueueSink):
pass
ic4.Library.init(api_log_level=ic4.LogLevel.INFO, log_targets=ic4.LogTarget.STDERR)
for _ in range(20):
device_list = ic4.DeviceEnum.devices()
found_dev = None
for dev in device_list:
print(f"{dev.model_name} ({dev.serial}) [{dev.interface.display_name}]")
if dev.model_name == "DMM 37UX265-ML":
found_dev = dev
if found_dev is None:
print("No device matching foound")
sys.exit(1)
grabber = ic4.Grabber()
grabber.device_open(found_dev)
grabber.device_property_map.set_value(ic4.PropId.USER_SET_SELECTOR, "Default")
grabber.device_property_map.execute_command(ic4.PropId.USER_SET_LOAD)
grabber.device_property_map.set_value(ic4.PropId.PIXEL_FORMAT, ic4.PixelFormat.Mono16)
grabber.device_property_map.set_value(ic4.PropId.WIDTH, 1024)
grabber.device_property_map.set_value(ic4.PropId.HEIGHT, 768)
grabber.device_property_map.set_value(ic4.PropId.BINNING_VERTICAL, 2)
grabber.device_property_map.set_value(ic4.PropId.BINNING_HORIZONTAL, 2)
grabber.device_property_map.set_value(ic4.PropId.OFFSET_AUTO_CENTER, "Off")
grabber.device_property_map.set_value(ic4.PropId.OFFSET_X, 0)
grabber.device_property_map.set_value(ic4.PropId.OFFSET_Y, 0)
grabber.device_property_map.set_value(ic4.PropId.EXPOSURE_AUTO, "Off")
grabber.device_property_map.set_value(ic4.PropId.EXPOSURE_TIME, 500) # microseconds
grabber.device_property_map.set_value(ic4.PropId.GAIN_AUTO, "Off")
grabber.device_property_map.set_value(ic4.PropId.GAIN, 0) # dB
grabber.device_property_map.set_value(ic4.PropId.GAMMA, 1)
fps = grabber.device_property_map[ic4.PropId.ACQUISITION_FRAME_RATE].maximum
interval_ns = (1/fps)*1e9
grabber.device_property_map.set_value(ic4.PropId.ACQUISITION_FRAME_RATE, grabber.device_property_map[ic4.PropId.ACQUISITION_FRAME_RATE].maximum)
grabber.device_property_map.set_value(ic4.PropId.TRIGGER_MODE, "On") # allow to trigger images acquisition
listener = MyListener()
sink = ic4.QueueSink(listener, [ic4.PixelFormat.Mono16])
grabber.stream_setup(sink, setup_option=ic4.StreamSetupOption.ACQUISITION_START)
# time.sleep(1) # not working otherwise, probably initializing things
for _ in range(2000):
sleep_ns(interval_ns)
grabber.device_property_map.set_value(ic4.PropId.TRIGGER_SOFTWARE, True) # Trig image acquisition
time.sleep(1)
print(f"stream stats : {grabber.stream_statistics}")
grabber.acquisition_stop()
grabber.device_close()
Hello,
Is this the right place to ask questions? Using the IC4 SDK with some GigE cameras.
Assuming yes then can I get the IP address of a connected unit?
ic4::DeviceInfo
provides some details but less than I'd expect.
When checking is_streaming property, followig pops
File "......site-packages\imagingcontrol4\grabber.py", line 257, in is_streaming
return Library.core.ic4_grabber_is_streaming()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: this function takes at least 1 argument (0 given)
OS: Windows11
Python 3.11
Hello.
Not sure if this is the best place to ask but suddenly cannot connect to camera. It is on the network with a fixed IP address and plugged into a brand new Netgear POE switch.
Any thoughts?
>ipconfig_cmd.exe list
[2024-04-02 18:40:19.219] [error] [win32_named_pipes_thread.h:106] Failed to open pipe. system:2
[2024-04-02 18:40:19.219] [error] [rpc_client.cpp:300] Failed to connect to NamedPipe-server at id=ic4-gentl-gev_service_pipe_1.0.0.554. Error: system:2
Failed to connect to service, ec: 'system:2'
R:\apps\tis\gige\bin>ping 192.168.68.49
Pinging 192.168.68.49 with 32 bytes of data:
Reply from 192.168.68.49: bytes=32 time<1ms TTL=255
Reply from 192.168.68.49: bytes=32 time<1ms TTL=255
Reply from 192.168.68.49: bytes=32 time<1ms TTL=255
Reply from 192.168.68.49: bytes=32 time<1ms TTL=255
Ping statistics for 192.168.68.49:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 0ms, Maximum = 0ms, Average = 0ms
The IC4 Service appears to be running:
At first glance, it is not clear that the callback function framesQueued
runs in a different thread. Might this be documented a little more clearly?
The next question is can you run capture loop in a single thread? The answer seems to be yes, but with the inefficiency of polling.
The example code below is just to illustrate the concept. what would be great here is to make popOutputBuffer()
a blocking call when given an optional timeout - this would put the calling thread to sleep until either a frame is ready or the timeout expires. Similar to WaitObject() in the Windows API.
Just a thought. Thanks for listening.
//
class NullListener : public ic4::QueueSinkListener {
public:
// caution! this callback is in a different thread
void framesQueued(ic4::QueueSink& qsink) override {
// do nothing rather than popping a queued image
// auto image = qsink.popOutputBuffer();
}
}
// N.B. No error checking for brevity
int main()
{
ic4::initLibrary();
// 1 device. use it
auto device_list = ic4::DeviceEnum::enumDevices();
ic4::DeviceInfo di = device_list[0]
//
ic4::Grabber grabber;
grabber.deviceOpen(di.serial());
// create a queue sink with the null listener.
NullListener nl;
auto qsink = ic4::QueueSink::create(nl);
// hook up grabber sink and run grabber.
grabber.streamSetup(qsink, ic4::StreamSetupOption::AcquisitionStart);
// loop - this polled model is operating in the *same* thread
while (true) {
// image d'tor will handle image recycling
// make popOutputBuffer a blocking call?
auto image = qsink->popOutputBuffer(std::chrono::seconds(10));
if (!image)
continue;
// do work with the image ...
}
grabber.streamStop();
grabber.deviceClose();
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.