RGB与YUV色彩空间的相互转换_rgb转yuv颜色值-CSDN博客 (2024)

RGB与YUV色彩空间相互转换

原理

RGB与YUV空间的对应关系

根据电视原理的相关知识可知,RGB与的YUV对应关系为:
{ Y = 0.299 R + 0.587 G + 0.114 B U = − 0.1684 R − 0.3316 G + 0.5 B = 0.564 ( B − Y ) V = 0.5 R − 0.4187 G − 0.0813 B = 0.713 ( R − Y ) (1) \begin{cases} Y= 0.299\ R &+ 0.587\ G &+ 0.114\ B \\ U= -0.1684\ R &- 0.3316\ G &+ 0.5\ B &= 0.564\ (B-Y) \\ V= 0.5\ R &- 0.4187\ G &- 0.0813\ B &= 0.713\ (R-Y) \\ \end{cases} \tag{1} Y=0.299RU=0.1684RV=0.5R+0.587G0.3316G0.4187G+0.114B+0.5B0.0813B=0.564(BY)=0.713(RY)(1)
其中,为了使色差信号的动态范围控制在[-0.5, 0.5],需要进行量化前的归一化处理,需要引入数字色差信号的压缩系数(分别为0.564与0.713)。

量化电平的分配

参考《现代电视原理》7.4.2节“视频信号量化电平的分配”部分:

在进行8 bit量化时,需要在上下两端留出一定的余量,作为信号超越动态范围的保护带。具体地:

  • 对于亮度信号,在256级的上端留出20级,下端留出16级作为余量,即Y的动态范围为16—235
  • 对于两个色差信号,在256级的上端留出15级,下端留出16级作为余量,即U、V的动态范围为16—240
RGB与YUV色彩空间的相互转换_rgb转yuv颜色值-CSDN博客 (1)
RGB与YUV色彩空间的相互转换_rgb转yuv颜色值-CSDN博客 (2)

根据码电平数字表达式
量 化 等 级 = i n t { 量 化 等 级 最 大 值 − 量 化 等 级 最 小 值 模 拟 电 平 最 大 值 − 模 拟 电 平 最 小 值 × 对 应 的 数 字 电 平 公 式 + 0 电 平 对 应 得 量 化 等 级 } (2) 量化等级={\rm{int}}\left\{ \dfrac{量化等级最大值-量化等级最小值}{模拟电平最大值-模拟电平最小值}\times 对应的数字电平公式+0电平对应得量化等级 \right\} \tag{2} =int{×+0}(2)
可知
{ Y ′ = i n t { 235 − 16 0.5 − ( − 0.5 ) Y + 16 } U ′ = i n t { 240 − 16 1 − 0 U + 128 } V ′ = i n t { 240 − 16 1 − 0 V + 128 } (3) \begin{cases} Y' = {\rm int}\left\{\dfrac {235-16}{0.5-(-0.5)}Y+16 \right\}\\ U' = {\rm int}\left\{\dfrac {240-16}{1-0}U+128 \right\}\\ V' = {\rm int}\left\{\dfrac {240-16}{1-0}V+128 \right\} \end{cases} \tag{3} Y=int{0.5(0.5)23516Y+16}U=int{1024016U+128}V=int{1024016V+128}(3)
其中,

  • i n t {\rm int} int表示向下取整;
  • Y ′ Y' Y U ′ U' U V ′ V' V为数字量化电平, Y Y Y U U U V V V为归一化的模拟电平( Y ∈ [ 0 , 1 ] Y\in [0,1] Y[0,1] U , V ∈ [ − 0.5 , 0.5 ] U,V\in [-0.5,0.5] U,V[0.5,0.5]);
  • 考虑到色差信号有负值,需要将原来的0值对应到128,故加上128。

由于读取的RGB文件已经进行了8 bit的量化(RGB三个分量范围均为0—255),所以要对公式 ( 2 ) (2) (2)进行修正,先将 Y Y Y映射到-0.5—0.5, U U U V V V映射到0—1:
{ Y ′ = i n t { 219 255 Y + 16 } U ′ = i n t { 224 255 U + 128 } V ′ = i n t { 224 255 V + 128 } (4) \begin{cases} Y' = {\rm int}\left\{ \dfrac {219}{255}Y+16 \right\}\\ U' = {\rm int}\left\{ \dfrac {224}{255}U+128 \right\}\\ V' = {\rm int}\left\{ \dfrac {224}{255}V+128 \right\} \end{cases} \tag{4} Y=int{255219Y+16}U=int{255224U+128}V=int{255224V+128}(4)
带入 ( 1 ) (1) (1)式,得:
{ Y = 66 R + 129 G + 25 B 255 + 16 U = − 38 R − 74 G + 112 B 255 + 128 V = 112 R − 94 G − 18 B 255 + 128 (5) \begin{cases} Y= \dfrac {66R + 129G + 25B}{255} + 16 \\ U= \dfrac{-38R - 74G + 112B}{255} +128 \\ V= \dfrac{112R - 94G - 18B}{255} + 128 \end{cases} \tag{5} Y=25566R+129G+25B+16U=25538R74G+112B+128V=255112R94G18B+128(5)
为了提高计算机的计算效率且不会造成过大的误差,在程序中使用>> 8来代替除以255的计算。

( 5 ) (5) (5)式写为矩阵形式:
[ Y U V ] = 1 255 [ 66 129 25 − 38 − 74 112 112 − 94 − 18 ] [ R G B ] + [ 16 16 128 ] (6) \begin{bmatrix} Y \\ U \\ V \end{bmatrix} = \dfrac {1}{255} \begin{bmatrix} 66 & 129 & 25 \\ -38 & -74 & 112 \\ 112 & -94 & -18 \end{bmatrix} \begin{bmatrix} R \\ G \\ B \end{bmatrix} + \begin{bmatrix} 16 \\ 16 \\ 128 \end{bmatrix} \tag{6} YUV=2551663811212974942511218RGB+1616128(6)
并记 A = [ 66 129 25 − 38 − 74 112 112 − 94 − 18 ] \boldsymbol A= \begin{bmatrix} 66 & 129 & 25 \\ -38 & -74 & 112 \\ 112 & -94 & -18 \end{bmatrix} A=663811212974942511218

反解,得:
[ R G B ] = 255 A T [ Y − 16 U − 16 V − 128 ] (7) \begin{bmatrix} R \\ G \\ B \end{bmatrix} = 255\boldsymbol A^{\rm T} \begin{bmatrix} Y-16 \\ U-16 \\ V-128 \end{bmatrix} \tag{7} RGB=255ATY16U16V128(7)
由于 A − 1 \boldsymbol A^{-1} A1数量级较小,直接使用会造成较大的计算误差,因而转化为
[ R G B ] = 25 5 2 ⋅ ( 1 255 A T ) [ Y − 16 U − 16 V − 128 ] (8) \begin{bmatrix} R \\ G \\ B \end{bmatrix} = 255^2 \cdot \left(\dfrac 1 {255}\boldsymbol A^{\rm T}\right) \begin{bmatrix} Y-16 \\ U-16 \\ V-128 \end{bmatrix} \tag{8} RGB=2552(2551AT)Y16U16V128(8)
整理得:

R = (298 * Y + 411 * V - 57344) >> 8;G = (298 * Y - 101 * U - 211 * V + 34739) >> 8;B = (298 * Y + 519 * U - 71117) >> 8;

main函数的命令行参数

main函数实际上具有两个形参,int argcchar* argv[]。虽然很多情况下是缺省的,但在例如涉及文件的操作中,使用命令行参数可以为编程提供一定的便利。

设置方法如下:在Visual Studio中,依次点击菜单栏中的项目→项目属性,在项目属性页的配置属性菜单下,点击“调试”。通过浏览文件夹的方式设置工作目录,并在命令参数中输入n个字符串(以空格分隔)。

RGB与YUV色彩空间的相互转换_rgb转yuv颜色值-CSDN博客 (3)

命令行参数的设置

这些字符串将会自动传递给argv,作为其第1n个元素(第0个元素为"项目名.exe"),而argc的值为n+1

源代码

declarations.h

#pragma oncevoid rgbLookupTable();void yuvLookupTable();void rgb2yuv(FILE*, int, int, int, unsigned char*, unsigned char*, unsigned char*, unsigned char*);void yuv2rgb(FILE*, int, int, int, unsigned char*, unsigned char*, unsigned char*, unsigned char*);void errorData(int, unsigned char*, char* []);

rgb2yuv.cpp

#include <iostream>#include "declarations.h"int rgb66[256], rgb129[256], rgb25[256];int rgb38[256], rgb74[256], rgb112[256];int rgb94[256], rgb18[256];void rgbLookupTable(){for (int i = 0; i < 256; i++){rgb66[i] = 66 * i;rgb129[i] = 129 * i;rgb25[i] = 25 * i;rgb38[i] = 38 * i;rgb74[i] = 74 * i;rgb112[i] = 112 * i;rgb94[i] = 94 * i;rgb18[i] = 18 * i;}}void rgb2yuv(FILE* yuvFile, int rgbSize, int w, int h, unsigned char* rgbBuf, unsigned char* yBuf, unsigned char* uBuf, unsigned char* vBuf){unsigned char* uBuf444 = NULL;// 下采样前的U分量缓冲区unsigned char* vBuf444 = NULL;// 下采样前的V分量缓冲区uBuf444 = new unsigned char[rgbSize / 3];// 4:4:4格式vBuf444 = new unsigned char[rgbSize / 3];int pxNum = w * h;// RGB to YUV (4:4:4)for (int i = 0; i < pxNum; i++)// i为图像像素序号{unsigned char r = rgbBuf[3 * i + 2];// RGB图像第i个像素的R分量unsigned char g = rgbBuf[3 * i + 1];// RGB图像第i个像素的G分量unsigned char b = rgbBuf[3 * i];// RGB图像第i个像素的B分量//yBuf[i] = ((66 * r + 129 * g + 25 * b) >> 8) + 16;//uBuf444[i] = ((-38 * r - 74 * g + 112 * b) >> 8) + 128;//vBuf444[i] = ((112 * r - 94 * g - 18 * b) >> 8) + 128;rgbLookupTable();// 使用查找表,提高运算效率yBuf[i] = ((rgb66[r] + rgb129[g] + rgb25[b]) >> 8) + 16;uBuf444[i] = ((-rgb38[r] - rgb74[g] + rgb112[b]) >> 8) + 128;vBuf444[i] = ((rgb112[r] - rgb94[g] - rgb18[b]) >> 8) + 128;}// 4:4:4 to 4:2:0for (int i = 0; i < h; i += 2){for (int j = 0; j < w; j += 2){uBuf[i / 2 * w / 2 + j / 2] = uBuf444[i * w + j];vBuf[i / 2 * w / 2 + j / 2] = vBuf444[i * w + j];}}delete[]uBuf444;delete[]vBuf444;fwrite(yBuf, sizeof(unsigned char), rgbSize / 3, yuvFile);fwrite(uBuf, sizeof(unsigned char), rgbSize / 12, yuvFile);fwrite(vBuf, sizeof(unsigned char), rgbSize / 12, yuvFile);}

yuv2rgb.cpp

#include <iostream>#include "declarations.h"int yuv298[256], yuv411[256];int yuv101[256], yuv211[256];int yuv519[256];void yuvLookupTable(){for (int i = 0; i < 256; i++){yuv298[i] = 298 * i;yuv411[i] = 411 * i;yuv101[i] = 101 * i;yuv211[i] = 211 * i;yuv519[i] = 519 * i;}}void yuv2rgb(FILE* rgbFile, int yuvSize, int w, int h, unsigned char* yBuf, unsigned char* uBuf, unsigned char* vBuf, unsigned char* rgbBuf){unsigned char* uBuf444 = new unsigned char[yuvSize * 2 / 3];// 还原成4:4:4的U分量缓冲区unsigned char* vBuf444 = new unsigned char[yuvSize * 2 / 3];// 还原成4:4:4的V分量缓冲区int pxNum = w * h;// 图像中的总像素数// 4:2:0 to 4:4:4for (int i = 0; i < h / 2; i++)// i控制行{for (int j = 0; j < w / 2; j++)// j控制列{uBuf444[2 * i * w + 2 * j] = uBuf[i * w / 2 + j];uBuf444[2 * i * w + 2 * j + 1] = uBuf[i * w / 2 + j];uBuf444[2 * i * w + 2 * j + w] = uBuf[i * w / 2 + j];uBuf444[2 * i * w + 2 * j + w + 1] = uBuf[i * w / 2 + j];vBuf444[2 * i * w + 2 * j] = vBuf[i * w / 2 + j];vBuf444[2 * i * w + 2 * j + 1] = vBuf[i * w / 2 + j];vBuf444[2 * i * w + 2 * j + w] = vBuf[i * w / 2 + j];vBuf444[2 * i * w + 2 * j + w + 1] = vBuf[i * w / 2 + j];}}// YUV (4:4:4) to RGBfor (int i = 0; i < pxNum; i++){// 中间变量均使用int型,以保证足够的精度,防止溢出int y = yBuf[i];// YUV图像第i个像素的Y分量int u = uBuf444[i];// YUV图像第i个像素的U分量(4:4:4)int v = vBuf444[i];// YUV图像第i个像素的V分量(4:4:4)int r;int g;int b;yuvLookupTable();//r = (298 * y + 411 * v - 57344) >> 8;// 还原的RGB图像的R分量r = (yuv298[y] + yuv411[v] - 57344) >> 8;// 还原的RGB图像的R分量if (r < 0)r = 0;// 修正if (r > 255)r = 255;//g = (298 * y - 101 * u - 211 * v + 34739) >> 8;// 还原的RGB图像的G分量g = (yuv298[y] - yuv101[u] - yuv211[v] + 34739) >> 8;// 还原的RGB图像的G分量if (g < 0)g = 0;if (g > 255)g = 255;//b = (298 * y + 519 * u - 71117) >> 8;// 还原的RGB图像的B分量b = (yuv298[y] + yuv519[u] - 71117) >> 8;// 还原的RGB图像的B分量if (b < 0)b = 0;if (b > 255)b = 255;rgbBuf[3 * i + 2] = (unsigned char)r;// 还原的RGB图像的R分量rgbBuf[3 * i + 1] = (unsigned char)g;// 还原的RGB图像的G分量rgbBuf[3 * i] = (unsigned char)b;// 还原的RGB图像的B分量}delete[]uBuf444;delete[]vBuf444;fwrite(rgbBuf, sizeof(unsigned char), yuvSize * 2, rgbFile);}

errorData.cpp

#include <iostream>#include "declarations.h"using namespace std;void errorData(int yuvSize, unsigned char* rgbBuf, char* argv[]){FILE* rgbOriFile = NULL;// 原始RGB图像文件指针FILE* errorFile = NULL;// 误差数据文件指针const char* rgbOriName = argv[1];// 原始RGB图像文件名const char* errorName = argv[4];// 误差数据文件名// 打开文件if (fopen_s(&rgbOriFile, rgbOriName, "rb") == 0){cout << "Successfully opened " << rgbOriName << "." << endl;}else{cout << "Failed to open " << rgbOriName << "." << endl;exit(0);}if (fopen_s(&errorFile, errorName, "w") == 0){cout << "Successfully opened " << errorName << "." << endl;}else{cout << "Failed to open " << errorName << "." << endl;exit(0);}unsigned char* rgbOriBuf = new unsigned char[yuvSize * 2];fread(rgbOriBuf, sizeof(unsigned char), yuvSize * 2, rgbOriFile);// 将误差数据输出到csv文件fprintf(errorFile, "Pixel,B Error,G Error,R Error\n");for (int i = 0; i < yuvSize * 2 / 3; i++){fprintf(errorFile, "%d,%d,%d,%d\n", i, (int)abs(rgbBuf[3 * i] - rgbOriBuf[3 * i]), (int)abs(rgbBuf[3 * i + 1] - rgbOriBuf[3 * i + 1]), (int)abs(rgbBuf[3 * i + 2] - rgbOriBuf[3 * i + 2]));}delete[]rgbOriBuf;fclose(rgbOriFile);fclose(errorFile);}

main.cpp

#include <iostream>#include "declarations.h"using namespace std;int main(int argc, char* argv[]){FILE* rgbOriFilePtr = NULL;// 原RGB图像的文件指针FILE* yuvFilePtr = NULL;// YUV图像的文件指针FILE* rgbRecFilePtr = NULL;// 复原的RGB文件的文件指针const char* rgbOriFileName = argv[1];// 原RGB图像文件名const char* yuvFileName = argv[2];// YUV图像文件名const char* rgbRecFileName = argv[3];// 复原RGB图像文件名int width = 256;// 图像宽int height = 256;// 图像高int rgbFileSize;// RGB图像总字节数int yuvFileSize;// YUV图像总字节数unsigned char* rgbOriBuffer = NULL;// 原RGB图像缓冲区unsigned char* yBuffer = NULL;// Y分量缓冲区unsigned char* uBuffer = NULL;// U分量缓冲区unsigned char* vBuffer = NULL;// V分量缓冲区unsigned char* rgbRecBuffer = NULL;// 复原RGB图像缓冲区// 打开文件if (fopen_s(&rgbOriFilePtr, rgbOriFileName, "rb") == 0){cout << "Successfully opened " << rgbOriFileName << "." << endl;}else{cout << "Failed to open " << rgbOriFileName << "." << endl;exit(0);}if (fopen_s(&yuvFilePtr, yuvFileName, "wb+") == 0){cout << "Successfully opened " << yuvFileName << "." << endl;}else{cout << "Failed to open " << yuvFileName << "." << endl;exit(0);}if (fopen_s(&rgbRecFilePtr, rgbRecFileName, "wb") == 0){cout << "Successfully opened " << rgbRecFileName << "." << endl;}else{cout << "Failed to open " << rgbRecFileName << "." << endl;exit(0);}// 计算原RGB图像总字节数fseek(rgbOriFilePtr, 0L, SEEK_END);rgbFileSize = ftell(rgbOriFilePtr);rewind(rgbOriFilePtr);cout << "The space that " << rgbOriFileName << " accounts for is " << rgbFileSize << " Bytes = " << rgbFileSize / 1024 << " kB." << endl;yuvFileSize = rgbFileSize / 2;// 建立缓冲区rgbOriBuffer = new unsigned char[rgbFileSize];yBuffer = new unsigned char[rgbFileSize / 3];uBuffer = new unsigned char[rgbFileSize / 12];// 4:2:0格式vBuffer = new unsigned char[rgbFileSize / 12];rgbRecBuffer = new unsigned char[rgbFileSize];fread(rgbOriBuffer, sizeof(unsigned char), rgbFileSize, rgbOriFilePtr);// RGB图像读入缓冲区rgb2yuv(yuvFilePtr, rgbFileSize, width, height, rgbOriBuffer, yBuffer, uBuffer, vBuffer);yuv2rgb(rgbRecFilePtr, yuvFileSize, width, height, yBuffer, uBuffer, vBuffer, rgbRecBuffer);errorData(yuvFileSize, rgbRecBuffer, argv);delete[]rgbOriBuffer;delete[]yBuffer;delete[]uBuffer;delete[]vBuffer;delete[]rgbRecBuffer;fclose(rgbOriFilePtr);fclose(yuvFilePtr);fclose(rgbRecFilePtr);}

实验结果与误差分析

RGB与YUV色彩空间的相互转换_rgb转yuv颜色值-CSDN博客 (4)

down.rgb

RGB与YUV色彩空间的相互转换_rgb转yuv颜色值-CSDN博客 (5)

down_transformed.yuv

RGB与YUV色彩空间的相互转换_rgb转yuv颜色值-CSDN博客 (6)

down_recoverd.rgb

以上三张图分别是原RGB图像、通过RGB转换的YUV图像和通过YUV复原的RGB图像。对比第1、3张图,几乎通过肉眼分辨不出差别。为了量化误差,在程序中,利用errorData函数计算了两张RGB图像各像素的三个分量的误差,并输出到了csv文件中。

由于在C++中进行数据分析与可视化并不方便,考虑到数据量较大,因而采用R进行分析。

在R中分别作出boxplot和直方图:

errorData <- read.csv("errorData.csv")b.error <- errorData[, 2]g.error <- errorData[, 3]r.error <- errorData[, 4]boxplot(r.error, g.error, b.error, horizontal = TRUE, names = c("R Error", "G Error", "B Error"), col = c("coral2", "palegreen1", "skyblue1"))hist(r.error, freq = FALSE, xlab = "Pixel", ylab = "Frequency of R Error", col = "coral2")hist(g.error, freq = FALSE, xlab = "Pixel", ylab = "Frequency of G Error", col = "palegreen1")hist(b.error, freq = FALSE, xlab = "Pixel", ylab = "Frequency of B Error", col = "skyblue1")
RGB与YUV色彩空间的相互转换_rgb转yuv颜色值-CSDN博客 (7)
RGB与YUV色彩空间的相互转换_rgb转yuv颜色值-CSDN博客 (8)
RGB与YUV色彩空间的相互转换_rgb转yuv颜色值-CSDN博客 (9)
RGB与YUV色彩空间的相互转换_rgb转yuv颜色值-CSDN博客 (10)

可以再求出各分量误差的Empirical CDF:

> ecdf.r.error <- ecdf(r.error)> ecdf.g.error <- ecdf(g.error)> ecdf.b.error <- ecdf(b.error)> ecdf.r.error(5)[1] 0.9351196> ecdf.g.error(5)[1] 0.9855804> ecdf.b.error(5)[1] 0.8774567

图表显示,该色度空间的转换不能做到100%的准确。误差来源可能有:

  • 由于从4:4:4的RGB图像转换为4:2:0的YUV图像时,舍弃掉了3/4的色度信息,因而在还原为YUV文件时是无法还原出舍弃部分的色度信息的;
  • 在进行色彩空间转换的公式推导时,使用了移位运算代替了除法运算,并且在计算过程中存在多次四舍五入;
  • 在YUV向RGB的转换时,存在部分数据溢出。

但R、G、B分量分别有93.5%、98.6%、87.8%的像素误差小于等于5,因而该算法的色彩空间转换的误差并不大,效果是可以接受的;由于人眼对色度的敏感度远高于对亮度的敏感度,误差也在人眼的分辨能力之外。

实验中需要注意的问题

  1. 在进行RGB和YUV的转换时,要特别留意数组下标,保证不会越界;

  2. 在将YUV还原为RGB时,可能会出现数据溢出(如下图),因而三个分量都需要分别判断,若有溢出,要置为0或255;

  3. RGB与YUV色彩空间的相互转换_rgb转yuv颜色值-CSDN博客 (11)

    down_recovered.rgb(数据有溢出)

r = (yuv298[y] + yuv411[v] - 57344) >> 8;// 还原的RGB图像的R分量if (r < 0)r = 0;// 修正if (r > 255)r = 255;g = (yuv298[y] - yuv101[u] - yuv211[v] + 34739) >> 8;// 还原的RGB图像的G分量if (g < 0)g = 0;if (g > 255)g = 255;b = (yuv298[y] + yuv519[u] - 71117) >> 8;// 还原的RGB图像的B分量if (b < 0)b = 0;if (b > 255)b = 255;
r = (yuv298[y] + yuv411[v] - 57344) >> 8;// 还原的RGB图像的R分量if (r < 0)r = 0;// 修正if (r > 255)r = 255;g = (yuv298[y] - yuv101[u] - yuv211[v] + 34739) >> 8;// 还原的RGB图像的G分量if (g < 0)g = 0;if (g > 255)g = 255;b = (yuv298[y] + yuv519[u] - 71117) >> 8;// 还原的RGB图像的B分量if (b < 0)b = 0;if (b > 255)b = 255;
  1. 在转换过程中,中间变量要使用int型(4字节)而不能使用unsigned char型(只有1字节),为数据溢出留出空间。
RGB与YUV色彩空间的相互转换_rgb转yuv颜色值-CSDN博客 (2024)

References

Top Articles
Blacksburg.craigslist
Prosedur Permohonan Perkahwinan di Negeri Kelantan 2019
Raleigh Craigs List
Burkes Outlet Credit Card Sign In
Hemispheres Dothan Al
Temu Beanies
Wieting Funeral Home
What Auto Parts Stores Are Open
Rebecca Benedict Forum
Does Publix Have Sephora Gift Cards
Blind Guardian - The God Machine Review • metal.de
San Antonio Busted Newspaper
Wsisd Calendar
888-490-1703
James Cameron And Getting Trapped Inside Your Most Successful Creation
Rugged Gentleman Barber Shop Martinsburg Wv
2024 Coachella Predictions
Employment Vacancies - Find Jobs with our recruitment team
Rs3 Ranged Weapon
Craigslist Motorcycles Salem Oregon
Pheasant Chicks Tractor Supply
Taxi Driver Kdrama Dramacool
BCLC Launches PROLINE Sportsbook at B.C. Retail Locations
Elijah Vue latest: Two Rivers police confirm remains are those of boy missing since February
Swag Codes: The Ultimate Guide to Boosting Your Swagbucks Earnings - Ricky Spears
Aldi Sign In Careers
Taylorsince1909
Conner Westbury Funeral Home Griffin Ga Obituaries
Wall Street Journal Currency Exchange Rates Historical
1946 Chevy Truck For Sale Craigslist
Mcdonald Hours Near Me
Antonio Brown Football Reference
Demetrius Meach Nicole Zavala
9294027542
Greenbrier Bunker Tour Coupon
Fx Channel On Optimum
Heavenly Delusion Gif
600 Aviator Court Vandalia Oh 45377
Texas State Final Grades
Lubbock, Texas hotels, motels: rates, availability
Section 212 Metlife Stadium
Limestone Bank Hillview
Super Bowl 17 Ray Finkle
Ccga Address
CDER - UTENLANDSKE og NORSKE artister
Maria Butina Bikini
Slug Menace Rs3
Luaj Shah Falas
Noel Berry's Biography: Age, Height, Boyfriend, Family, Net Worth
Lakeridge Funeral Home Lubbock Texas Obituaries
Buzzn Dispensary
Perolamartinezts
Latest Posts
Article information

Author: Sen. Emmett Berge

Last Updated:

Views: 6300

Rating: 5 / 5 (80 voted)

Reviews: 95% of readers found this page helpful

Author information

Name: Sen. Emmett Berge

Birthday: 1993-06-17

Address: 787 Elvis Divide, Port Brice, OH 24507-6802

Phone: +9779049645255

Job: Senior Healthcare Specialist

Hobby: Cycling, Model building, Kitesurfing, Origami, Lapidary, Dance, Basketball

Introduction: My name is Sen. Emmett Berge, I am a funny, vast, charming, courageous, enthusiastic, jolly, famous person who loves writing and wants to share my knowledge and understanding with you.