Skip to content

Instantly share code, notes, and snippets.

@0V
Last active August 29, 2015 14:17
Show Gist options
  • Save 0V/5c73ecc036f0a80106c2 to your computer and use it in GitHub Desktop.
Save 0V/5c73ecc036f0a80106c2 to your computer and use it in GitHub Desktop.
ChromaKey From Capture
public static void ChromaKeyCaptureSum(int faceCameraId, int backCameraId, bool putText = true)
{
using (var form = new Form())
using (var trackbarHueMin = new TrackbarWithLabel("Hue (min)", 50, 180, 0))
using (var trackbarHueMax = new TrackbarWithLabel("Hue (max)", 70, 180, 0))
using (var trackbarSaturationMin = new TrackbarWithLabel("Saturation (min)", 80, 255, 0))
using (var trackbarSaturationMax = new TrackbarWithLabel("Saturation (max)", 255, 255, 0))
using (var trackbarValueMin = new TrackbarWithLabel("Value (min)", 0, 255, 0))
using (var trackbarValueMax = new TrackbarWithLabel("Value (max)", 255, 255, 0))
using (var faceCapture = new VideoCapture(faceCameraId))
using (var backCapture = new VideoCapture(backCameraId))
using (var faceWindow = new Window("Capture #Face #" + faceCameraId))
using (var backWindow = new Window("Capture #Back #" + backCameraId))
using (var resultWindow = new Window("Capture #ChromaKey #" + backCameraId))
{
var controls = new[]
{
trackbarHueMin,
trackbarHueMax,
trackbarSaturationMin,
trackbarSaturationMax,
trackbarValueMin,
trackbarValueMax
};
var height = trackbarHueMin.Height + 20;
form.Width = trackbarHueMin.Width + 50;
form.Height = height * controls.Count() + 20;
for (int i = 0; i < controls.Count(); i++)
{
controls[i].Top = height * i;
}
form.Controls.AddRange(controls);
form.Show();
if (!faceCapture.IsOpened())
{
throw new InvalidOperationException("Faceカメラが開けませんでした。");
}
else if (!backCapture.IsOpened())
{
throw new InvalidOperationException("カメラが開けませんでした。");
}
Mat mat = new Mat();
Mat bgMat = new Mat();
if (faceCapture.FrameHeight > backCapture.FrameHeight)
{
faceCapture.FrameHeight = backCapture.FrameHeight;
faceCapture.FrameWidth = backCapture.FrameWidth;
}
else
{
backCapture.FrameHeight = faceCapture.FrameHeight;
backCapture.FrameWidth = faceCapture.FrameWidth;
}
var textPoint = new CvPoint(backCapture.FrameWidth - 410, backCapture.FrameHeight - 10);
var textFontFace = FontFace.HersheyComplexSmall;
var textColor = new CvColor(243, 152, 0);
int hueMin = 100;
int hueMax = 160;
int saturationMin = 100;
int saturationMax = 160;
int valueMin = 100;
int valueMax = 160;
while (Cv2.WaitKey(1) < 0)
{
hueMin = trackbarHueMin.Trackbar.Value;
hueMax = trackbarHueMax.Trackbar.Value;
saturationMin = trackbarSaturationMin.Trackbar.Value;
saturationMax = trackbarSaturationMax.Trackbar.Value;
valueMin = trackbarValueMin.Trackbar.Value;
valueMax = trackbarValueMax.Trackbar.Value;
faceCapture.Read(mat);
backCapture.Read(bgMat);
var face = ChromaKey(mat, bgMat, hueMin, hueMax, saturationMin, saturationMax, valueMin, valueMax);
resultWindow.ShowImage(face);
if (putText)
{
mat.PutText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff K"), textPoint, textFontFace, 1, textColor);
bgMat.PutText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff K"), textPoint, textFontFace, 1, textColor);
}
faceWindow.ShowImage(mat);
backWindow.ShowImage(bgMat);
}
}
}
public static Mat ChromaKey(Mat srcMat, Mat backMat, int hueMin, int hueMax, int saturationMin, int saturationMax, int valueMin, int valueMax, int morphorogyIterations = 1)
{
var mask = ColorExtractionMask(srcMat, ColorConversion.BgrToHsv, hueMin, hueMax, saturationMin, saturationMax, valueMin, valueMax); var element = new Mat();
var back = new Mat();
var face = new Mat();
var result = new Mat();
Cv2.MorphologyEx(mask, mask, MorphologyOperation.Close, element, null, morphorogyIterations);
Cv2.MorphologyEx(mask, mask, MorphologyOperation.Open, element, null, morphorogyIterations);
var reverseMask = ~mask;
srcMat.CopyTo(face, reverseMask);
backMat.CopyTo(back, mask);
Cv2.Add(back, face, result);
mask.Dispose();
element.Dispose();
back.Dispose();
face.Dispose();
reverseMask.Dispose();
return result;
}
public static Mat ColorExtractionMask(Mat srcMat, ColorConversion code,
int ch1Lower, int ch1Upper,
int ch2Lower, int ch2Upper,
int ch3Lower, int ch3Upper)
{
if (srcMat == null)
throw new ArgumentNullException("srcMat");
var colorMat = srcMat.CvtColor(code);
var lut = new Mat(256, 1, MatType.CV_8UC3);
var lower = new int[3] { ch1Lower, ch2Lower, ch3Lower };
var upper = new int[3] { ch1Upper, ch2Upper, ch3Upper };
// cv::Mat_<cv::Vec3b>
var mat3 = new MatOfByte3(lut);
var indexer = mat3.GetIndexer();
for (int i = 0; i < 256; i++)
{
var color = indexer[i];
byte temp;
for (int k = 0; k < 3; k++)
{
if (lower[k] <= upper[k])
{
if ((lower[k] <= i) && (i <= upper[k]))
{
temp = 255;
}
else
{
temp = 0;
}
}
else
{
if ((i <= upper[k]) || (lower[k] <= i))
{
temp = 255;
}
else
{
temp = 0;
}
}
color[k] = temp;
}
indexer[i] = color;
}
Cv2.LUT(colorMat, lut, colorMat);
var channelMat = colorMat.Split();
var maskMat = new Mat();
Cv2.BitwiseAnd(channelMat[0], channelMat[1], maskMat);
Cv2.BitwiseAnd(maskMat, channelMat[2], maskMat);
colorMat.Dispose();
lut.Dispose();
mat3.Dispose();
channelMat[0].Dispose();
channelMat[1].Dispose();
channelMat[2].Dispose();
return maskMat;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment