今天晚上在调试颜色阈值时,为了确定红色和绿色的颜色分割阈值,我想要创建滚动条以更加方便的调试。那么问题来了:opencv中的cvCreateTrackbar函数只能够修改一个参数的值,而我想要同时调整红色和绿色的颜色分割阈值,需要调节两个参数。
解决方法是在文件中声明全局变量,然后在同一个window上使用两次cvCreateTrackbar函数中,注意在每一个cvCreateTrackbar函数中,第3个参数分别传入不同的全局变量,然后在回调函数中,使用这两个全局变量,这样每一个滚动条会控制一个全局变量,滑动不同的滚动条,这样就可以控制回调函数中的多个待调整参数了。
声明全局变量:
static int high = 200;//红色 static int low = 100;//绿色主函数:
int main() { IplImage *img; img = cvLoadImage("test0.jpg"); colorSegmentation(100); //随便传一个参数就好,反正也不使用 cvCreateTrackbar("low_green", "result", &low, 255, colorSegmentation);//连续在同一个窗口创建两次滚动条 cvCreateTrackbar("high_red", "result", &high, 255, colorSegmentation); cvWaitKey(); }回调函数中实现的是将图像从RGB颜色空间转换到LAB颜色空间,分离出A通道,根据A通道的像素值对其进行标记,红色像素标记为灰色,绿色像素标记为白色,其他颜色像素标记为黑色:
void colorSegmentation(/*IplImage* inputImage,*/int lown)//其实该回调函数根本没有使用lown,只是为了满足cvCreateTrackbar中的回调函数声明类型才设置的 { IplImage *inputImage = cvLoadImage("test2.jpg"); IplImage *IMG_LAB, *IMG_A,*IMG_OUT; IMG_LAB = cvCreateImage(cvGetSize(inputImage), inputImage->depth, 3); IMG_A = cvCreateImage(cvGetSize(inputImage), inputImage->depth, 1); IMG_OUT = cvCreateImage(cvGetSize(inputImage), inputImage->depth, 1); cvCvtColor(inputImage, IMG_LAB, CV_BGR2Lab); cvSplit(IMG_LAB, 0, IMG_A, 0, 0); cvShowImage("A",IMG_A); cvWaitKey(20); if (!IMG_A) exit(EXIT_FAILURE); int iHeight = IMG_A->height; int iWidth = IMG_A->width; int iOutWidthStep = IMG_A->widthStep;//widthStep 表示存储一行像素所需的字节数 int Green_num = 0, Red_num = 0; int value;//存储单通道图像中的像素值 unsigned char* in = (unsigned char*)IMG_A->imageData; unsigned char* out = (unsigned char*)IMG_OUT->imageData; for (int j = 0; j<iHeight; j++) { in = (unsigned char*)IMG_A->imageData + j*iOutWidthStep; out = (unsigned char*)IMG_OUT->imageData + j*iOutWidthStep; for (int i = 0; i<iWidth; i++){ value = in[i];//存储的是A通道的值 if (value<low) { out[i] = GREEN_PIXEL_LABEL; Green_num++; } else if (value>high)//原来程序的阈值 { out[i] = RED_PIXEL_LABEL; Red_num++; } else out[i] = NON_BLOB_PIXEL_LABEL; } } cvShowImage("result",IMG_OUT); cvWaitKey(20); cvReleaseImage(&IMG_A); cvReleaseImage(&IMG_LAB); cvReleaseImage(&IMG_OUT); }
运行效果: