matlab/matlab-enhance-camera-image
> Read BEFORE troubleshooting or enhancing camera image quality. Diagnoses and enhances image quality from cameras connected via Image Acquisition Toolbox or USB Webcams support package. Discovers camera capabilities at runtime, analyzes captured images for quality issues (brightness, contrast, sharpness, noise, color balance, backlighting), suggests hardware setting adjustments tailored to the specific camera, and applies Image Processing Toolbox enhancement functions. Use when a user wants to improve camera image quality, troubleshoot dark/blurry/noisy/grainy/ overexposed/washed out/color cast images, or optimize camera settings.
npx skills add https://github.com/matlab/matlab-agentic-toolkit --skill matlab-enhance-camera-image
Diagnose image quality issues from any connected camera and improve them through a combination of hardware setting adjustments and software post-processing. Operates in a hardware-first, software-second philosophy: always try to fix at the source before resorting to post-processing.
scripts/diagnoseImageQuality.m — reusable diagnostic function; takes an image, returns a struct of quality metrics with assessmentsdetect_matlab_toolboxes first to confirm Image Acquisition Toolbox and Image Processing Toolbox are installedcheck_matlab_code on any script before executing itAPI selection: When Image Acquisition Toolbox is available, always prefer videoinput over other interfaces like webcam(). videoinput exposes more properties (via propinfo), supports bulk frame acquisition (getdata), and provides FramesAcquiredFcn for streaming. Use webcam() only when Image Acquisition Toolbox is not installed and the user has the MATLAB Support Package for USB Webcams instead.
Connect to the camera and enumerate all available properties:
% For videoinput (preferred when Image Acquisition Toolbox is available):
vid = videoinput(adaptorName, deviceID, format);
vid.ReturnedColorSpace = 'rgb'; % Critical for YUY2 cameras
src = getselectedsource(vid);
props = properties(src);
% For webcam (fallback when only USB Webcams support package is installed):
cam = webcam();
props = properties(cam);
Classify each discovered property by function:
| Problem Domain | Common Property Names |
|---|---|
| Brightness/Exposure | Exposure, ExposureTime, ExposureMode, Brightness, Gain, BacklightCompensation |
| Focus | Focus, FocusMode |
| Color | WhiteBalance, WhiteBalanceMode, Hue, Saturation, ColorEnable |
| Contrast/Tone | Contrast, Gamma, Sharpness |
Record valid ranges for each property. Report discovered capabilities to the user.
For properties that do NOT match the classification table above, apply the advanced property investigation protocol:
videoinput sources, use propinfo(src, propName) to determine type, constraint, range, and read-only statusFor videoinput objects (preferred):
% Warm up the camera (critical — first frames are often blank or poorly exposed)
preview(vid);
pause(2);
closepreview(vid);
% Capture the reference image
baselineImg = getsnapshot(vid);
imshow(baselineImg);
title("Baseline Image");
For webcam objects (fallback):
% Warm up the camera (critical — first frames are often blank or poorly exposed)
preview(cam);
pause(2);
closePreview(cam);
% Capture the reference image
baselineImg = snapshot(cam);
imshow(baselineImg);
title("Baseline Image");
Note: snapshot() is webcam-only. For videoinput, use getsnapshot(vid). Both webcam and videoinput objects support preview().
Record current property values as baseline for comparison.
Before running diagnostics, identify what the user is trying to fix:
Map the user's concern to one of these categories:
diagnoseImageQuality.m): brightness, contrast, sharpness, noise, color balance, backlightingIf the concern is an extended one, note it for dynamic evaluation in Step 4.
Run the diagnostic script (always — provides the standard baseline):
addpath("scripts");
results = diagnoseImageQuality(baselineImg);
disp(results);
The function returns a struct with fields:
brightness — mean intensity, assessmentclipping — highlight clipping (% pixels ≥ 250) and shadow clipping (% pixels ≤ 5), assessmentcontrast — standard deviation, assessmentsharpness — Laplacian variance, assessmentnoise — estimated noise level, assessmentcolorBalance — R/G and B/G ratios, assessmentbacklightRatio — center-vs-border brightness ratio, assessmentEach field has .value (numeric or struct) and .assessment ("OK", "Problem", or "Severe").
Identify the primary issue(s) — focus on fields assessed as "Problem" or "Severe".
Dynamic evaluation for extended concerns: If the user's concern from Step 3 is not covered by the standard 6 metrics, generate inline MATLAB code to evaluate it. See references/diagnosis-guidance.md § "Extended Metrics" for evaluation patterns and code templates. Report the extended metric result alongside the standard results.
Map diagnosed problems to available camera properties using the decision table below. Only suggest adjustments for properties the camera actually has.
Apply settings, re-capture, and compare metrics. Change one property at a time.
For videoinput objects (preferred):
% Example: increase exposure for dark image
src.Exposure = src.Exposure + 2;
newImg = getsnapshot(vid);
newResults = diagnoseImageQuality(newImg);
For webcam objects (fallback):
% Example: increase exposure for dark image
cam.Exposure = cam.Exposure + 2;
newImg = snapshot(cam);
newResults = diagnoseImageQuality(newImg);
Note: With videoinput, set properties on the source object (src), not the videoinput object. Use getsnapshot(vid) instead of snapshot().
Iterate if needed until metrics improve or hardware options are exhausted.
Based on remaining issues after hardware adjustment, apply IPT functions in the correct order:
imlocalbrighten, imadjust, gamma correctionlocallapfilt, adapthisteq on luminance channelimsharpen — always lastenhanced = baselineImg;
% Example: brighten a backlit image
enhanced = imlocalbrighten(enhanced, 0.8);
% Example: enhance local contrast
enhanced = locallapfilt(enhanced, 0.3, 1.5);
% Example: sharpen (last step)
enhanced = imsharpen(enhanced, 'Radius', 1.5, 'Amount', 1.0);
Display before/after comparison:
montage({baselineImg, enhanced}, 'Size', [1 2]);
title("Before vs After Enhancement");
Summarize the full workflow:
Generate a reusable .m function file that the user can call for future captures without the agent. Write it to a user-specified folder if provided, otherwise to the current MATLAB working directory (pwd). Do NOT write it to the skill's scripts/ folder — that is reserved for the skill's own helper functions.
After writing the file:
check_matlab_code on it to verify syntaxThe function should:
ReturnedColorSpace = 'rgb' if the camera outputs YUY2 or other non-RGB format| Diagnosed Problem | Hardware Fix (if available) | Software Fix (IPT) |
|---|---|---|
| Subject too dark (backlit) | BacklightCompensation ↑, Exposure ↑, Brightness ↑ | imlocalbrighten, inverted imreducehaze |
| Overall underexposed | Exposure ↑, Gain ↑, Brightness ↑ | Gamma correction (.^ 0.7), imadjust |
| Overall overexposed | Exposure ↓, Brightness ↓ | imadjust with output range [0 0.8] |
| Low contrast | Contrast ↑, Gamma adjust | locallapfilt, adapthisteq on luminance |
| Motion blur | Exposure ↓ (faster shutter) | imsharpen (limited), deconvolution |
| Out of focus | Focus adjust (if available) | imsharpen (limited help) |
| High noise | Gain ↓, Exposure ↑ instead | imgaussfilt, imnlmfilt, wiener2 |
| Color cast | WhiteBalance adjust, WhiteBalanceMode=auto | Manual white point correction |
| Washed out | Gamma ↓, Contrast ↑ | imadjust, locallapfilt |
Replace placeholders with discovered values. Only include enhancement steps that measurably improved metrics.
function img = acquireEnhancedImage()
%acquireEnhancedImage Capture and enhance image from <camera name>.
% img = acquireEnhancedImage() returns an enhanced RGB image.
vid = videoinput('<adaptor>', <deviceID>, '<format>');
vid.ReturnedColorSpace = 'rgb';
src = getselectedsource(vid);
% Tuned hardware settings
src.<Property1> = <value>;
src.<Property2> = <value>;
% Warm up
preview(vid);
pause(2);
closepreview(vid);
% Capture
img = getsnapshot(vid);
delete(vid);
% Enhancement pipeline (only steps that helped)
img = imlocalbrighten(img, <amount>);
img = imgaussfilt(img, <sigma>);
end
Naming: use acquireEnhancedImage as default, or ask user for a preferred name. Follow lowerCamelCase. See references/enhancement-guidance.md § "Generating Reusable Functions" for parameterization and optional-input guidance.
localtonemap requires single input — always convert with im2single() first; passing uint8 throws an errorpreview() or discard initial snapshots before capturingadapthisteq (CLAHE) needs a single-channel image — apply on V channel (HSV) or L channel (Lab), not directly on RGBimlocalbrighten only lifts dark regions — preserves already-bright areas; preferred over global brightness increase for backlit scenesReturnedColorSpace = 'rgb' — many USB webcams (e.g., Microsoft LifeCam) only output YUY2. Without setting vid.ReturnedColorSpace = 'rgb', getsnapshot returns raw YCbCr data misinterpreted as RGB, causing wrong colors in display AND incorrect results from IPT functions and diagnostic metricssnapshot vs getsnapshot — snapshot(cam) is webcam-only; getsnapshot(vid) is for videoinput objects. They are not interchangeableclosePreview vs closepreview — webcam uses camelCase closePreview(cam); videoinput uses lowercase closepreview(vid). Using the wrong case throws "Undefined command/function"getdata — for multi-frame capture with videoinput, use getdata(vid, N) instead of looping getsnapshot. It fetches N frames in one call with less overhead and lets the adaptor run at full speedfullfile for file saves — when saving images or generated files, use fullfile(pwd, 'filename.png') to avoid path resolution errors across platforms----
Copyright 2026 The MathWorks, Inc.
----
Take matlab/matlab-enhance-camera-image from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.