cv::MatからIplImageへの変換
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
//変換元画像
cv::Mat mat(240, 320, CV_8UC3);
//変換先画像
IplImage iplImage = mat; //ポインターではない(実体)
IplImage iplImage2 = mat; // 〃
//後始末について
//変換先画像を以下のように無理に解放してはいけない。
// IplImage* pIplImage = &iplImage;
// cvReleaseImage(&pIplImage);
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
IplImageからcv::Matへの変換
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
//変換元画像
IplImage* iplImage = cvCreateImage(cvSize(320,240), IPL_DEPTH_8S, 3);
//変換先画像
cv::Mat mat(iplImage); //(1)コピーコンストラクタ
cv::Mat mat2;
mat2 = iplImage; //(2)ポインタの代入
//後始末について
cvReleaseImage(&iplImage);//元画像は開放すべき
/**
* 抽出された赤系色イメージを生成する
* @param orgImage 元イメージ
* @return 生成イメージ
*/
+ (UIImage *)createExtractedRedElementColorImage:(UIImage *)orgImage
{
IplImage *srcIpl = [OpenCVManager createIplImageFromUIImage:orgImage];
IplImage *dstIpl = cvCreateImage(cvGetSize(srcIpl), IPL_DEPTH_8U, 3);
[self extractColorWithSrcImage:srcIpl
dstImage:dstIpl
code:CV_BGR2HSV
ch1Lower:170
ch1Upper:10
ch2Lower:80
ch2Upper:255
ch3Lower:0
ch3Upper:255];
UIImage *image = [OpenCVManager createUIImageFromIplImage:dstIpl];
cvReleaseImage(&dstIpl);
cvReleaseImage(&srcIpl);
return image;
}
/**
* 閾値指定(HSV)による色を抽出する
* @param src_img 入力画像(8bit3ch) 4chの間違い?
* @param dst_img 出力画像(8bit3ch)
* @param code 色空間の指定(CV_BGR2HSV,CV_BGR2Labなど)
* @param ch1_lower ch1のしきい値(小)
* @param ch1_upper ch1のしきい値(大)
* @param ch2_lower ch2のしきい値(小)
* @param ch2_upper ch2のしきい値(大)
* @param ch3_lower ch3のしきい値(小)
* @param ch3_upper ch3のしきい値(大)
* @remarks lower <= upperの場合、lower以上upper以下の範囲を抽出、
* lower > upperの場合、upper以下lower以上の範囲を抽出します。
*/
+ (void)extractColorWithSrcImage:(IplImage *)src_img
dstImage:(IplImage *)dst_img
code:(int)code
ch1Lower:(int)ch1_lower
ch1Upper:(int)ch1_upper
ch2Lower:(int)ch2_lower
ch2Upper:(int)ch2_upper
ch3Lower:(int)ch3_lower
ch3Upper:(int)ch3_upper
{
int i, k;
IplImage *Color_img;
IplImage *ch1_img, *ch2_img, *ch3_img;
IplImage *Mask_img;
int lower[3];
int upper[3];
int val[3];
CvMat *lut;
//codeに基づいたカラー変換
Color_img = cvCreateImage(cvGetSize(src_img), src_img->depth, src_img->nChannels);
cvCvtColor(src_img, Color_img, code);
//3ChのLUT作成
lut = cvCreateMat(256, 1, CV_8UC3);
lower[0] = ch1_lower;
lower[1] = ch2_lower;
lower[2] = ch3_lower;
upper[0] = ch1_upper;
upper[1] = ch2_upper;
upper[2] = ch3_upper;
for (i = 0; i < 256; i++){
for (k = 0; k < 3; k++){
if (lower[k] <= upper[k]){
if ((lower[k] <= i) && (i <= upper[k])){
val[k] = 255;
}else{
val[k] = 0;
}
}else{
if ((i <= upper[k]) || (lower[k] <= i)){
val[k] = 255;
}else{
val[k] = 0;
}
}
}
//LUTの設定
cvSet1D(lut, i, cvScalar(val[0], val[1], val[2]));
}
//3ChごとのLUT変換(各チャンネルごとに2値化処理)
cvLUT(Color_img, Color_img, lut);
cvReleaseMat(&lut);
//各チャンネルごとのIplImageを確保する
ch1_img = cvCreateImage(cvGetSize(Color_img), Color_img->depth, 1);
ch2_img = cvCreateImage(cvGetSize(Color_img), Color_img->depth, 1);
ch3_img = cvCreateImage(cvGetSize(Color_img), Color_img->depth, 1);
//チャンネルごとに二値化された画像をそれぞれのチャンネルに分解する
cvSplit(Color_img, ch1_img, ch2_img, ch3_img, NULL);
//3Ch全てのANDを取り、マスク画像を作成する。
Mask_img = cvCreateImage(cvGetSize(Color_img), Color_img->depth, 1);
cvAnd(ch1_img, ch2_img, Mask_img);
cvAnd(Mask_img, ch3_img, Mask_img);
//入力画像(src_img)のマスク領域を出力画像(dst_img)へコピーする
cvZero(dst_img);
cvCopy(src_img, dst_img, Mask_img);
//解放
cvReleaseImage(&Color_img);
cvReleaseImage(&ch1_img);
cvReleaseImage(&ch2_img);
cvReleaseImage(&ch3_img);
cvReleaseImage(&Mask_img);
}
#if TRUE
// 外接矩形(回転なし)を描画する
cv::Rect brect = cv::boundingRect(cv::Mat(targetCorners).reshape(2));
p2f[0] = brect.tl();
p2f[1] = cv::Point2f(brect.tl().x, brect.br().y);
p2f[2] = brect.br();
p2f[3] = cv::Point2f(brect.br().x, brect.tl().y);
rectangle(orgMat, brect.tl(), brect.br(), Scalar(255, 0, 0), 2, CV_AA);
#else
// 外接矩形(回転あり)を描画する
cv::RotatedRect box = cv::minAreaRect(cv::Mat(targetCorners).reshape(2));
box.points(p2f);
for (int i = 0; i < 4; i++) {
cv::line(orgMat, p2f[i], p2f[i<3?i+1:0], cv::Scalar(255, 0, 0), 2, CV_AA);
}
#endif
最終更新:2018年03月29日 09:44