今天晚上在调试颜色阈值时,为了确定红色和绿色的颜色分割阈值,我想要创建滚动条以更加方便的调试。那么问题来了: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);
}
原图像:
运行效果: