我正在尝试为程序编写算法,以在图像上绘制均匀的垂直渐变。即我想沿着图像的m行更改像素颜色从0到255,但是找不到一个好的通用算法。
我尝试使用opencv实现类似的功能,但它似乎无法正常工作
[{"id":2,"company_name":"Test Company","address1":"abc","address2":"def","po_box":"1234","city_id":2,"email":"lklk@lklk.com","phone":"9898","fax_no":9798,"website":"www.jgjh.com","corporate_code":null,"contact_person_first_name":"First","contact_person_last_name":"Last","contact_person_phone":"98989","contact_person_email":"kjskdjk@kjdkaj.com"},{"id":3,"company_name":"Test Company","address1":"abc","address2":"def","po_box":"1234","city_id":2,"email":"lklk@lklk.com","phone":"9898","fax_no":9798,"website":"www.jgjh.com","corporate_code":null,"contact_person_first_name":"First","contact_person_last_name":"Last","contact_person_phone":"98989","contact_person_email":"kjskdjk@kjdkaj.com"},{"id":4,"company_name":"Test Company","address1":"abc","address2":"def","po_box":"1234","city_id":2,"email":"lklk@lklk.com","phone":"9898","fax_no":9798,"website":"www.jgjh.com","corporate_code":"17","contact_person_first_name":"First","contact_person_last_name":"Last","contact_person_phone":"98989","contact_person_email":"kjskdjk@kjdkaj.com"},{"id":5,"company_name":"Test Company","address1":"abc","address2":"def","po_box":"1234","city_id":2,"email":"lklk@lklk.com","phone":"9898","fax_no":9798,"website":"www.jgjh.com","corporate_code":"17","contact_person_first_name":"First","contact_person_last_name":"Last","contact_person_phone":"98989","contact_person_email":"kjskdjk@kjdkaj.com"},{"id":6,"company_name":"Test Company","address1":"abc","address2":"def","po_box":"1234","city_id":2,"email":"lklk@lklk.com","phone":"9898","fax_no":9798,"website":"www.jgjh.com","corporate_code":"18","contact_person_first_name":"First","contact_person_last_name":"Last","contact_person_phone":"98989","contact_person_email":"kjskdjk@kjdkaj.com"},{"id":7,"company_name":"Test Company","address1":"abc","address2":"def","po_box":"1234","city_id":2,"email":"lklk@lklk.com","phone":"9898","fax_no":9798,"website":"www.jgjh.com","corporate_code":"19","contact_person_first_name":"First","contact_person_last_name":"Last","contact_person_phone":"98989","contact_person_email":"kjskdjk@kjdkaj.com"},{"id":8,"company_name":"Test Company","address1":"abc","address2":"def","po_box":"1234","city_id":2,"email":"lklk@lklk.com","phone":"9898","fax_no":9798,"website":"www.jgjh.com","corporate_code":"20","contact_person_first_name":"First","contact_person_last_name":"Last","contact_person_phone":"98989","contact_person_email":"kjskdjk@kjdkaj.com"},{"id":9,"company_name":"Test Company","address1":"abc","address2":"def","po_box":"1234","city_id":2,"email":"lklk@lklk.com","phone":"9898","fax_no":9798,"website":"www.jgjh.com","corporate_code":"21","contact_person_first_name":"First","contact_person_last_name":"Last","contact_person_phone":"98989","contact_person_email":"kjskdjk@kjdkaj.com"},{"id":10,"company_name":"Test Company","address1":"abc","address2":"def","po_box":"1234","city_id":2,"email":"lklk@lklk.com","phone":"9898","fax_no":9798,"website":"www.jgjh.com","corporate_code":"22","contact_person_first_name":"First","contact_person_last_name":"Last","contact_person_phone":"98989","contact_person_email":"kjskdjk@kjdkaj.com"},{"id":11,"company_name":"Test Company","address1":"abc","address2":"def","po_box":"1234","city_id":2,"email":"lklk@lklk.com","phone":"9898","fax_no":9798,"website":"www.jgjh.com","corporate_code":"23","contact_person_first_name":"First","contact_person_last_name":"Last","contact_person_phone":"98989","contact_person_email":"kjskdjk@kjdkaj.com"}]
答案 0 :(得分:3)
解决这个问题需要了解三个简单的技巧:
<强> 1。插值:强>
从一个值逐渐变为另一个值的过程称为interpolation。插值颜色值有多种方法:最简单的方法是线性插入每个组件,即以下列形式:
interpolated = start * (1-t) + dest * t
。
其中
start
是您要向值dest
进行插值的值。t
表示内插值与目标值dest
的接近程度,其范围为0
到1
,0
为纯start
{1}}颜色和1
是纯dest
颜色。您会发现RGB色彩空间中的线性插值不会产生自然色彩路径。作为高级步骤,您可以使用HSV颜色空间。有关颜色插值的详细信息,请参阅this question。
<强> 2。离散化:强>
不幸的是,插值产生实数。因此,我们必须使它们离散,以便能够将它们用作整数颜色值。执行此操作的最佳方法是使用例如舍入到最接近的整数。 C ++中的round()
。
第3。找到插值点:
现在,我们只需要在图像的每一行都有一个实值插值点t
。我们可以通过分析我们想要看到的输出来推断出这个公式:
t == 0
,因为这是我们希望我们的纯启动颜色出现的地方。 t == 1
,因为这是我们希望显示纯目标颜色的地方。t
每隔一行线性缩放到最底行的距离。实现这一结果的公式是:
t = rowIndex / m
通过适当改变这个公式,该方法可以很容易地适应其他梯度方向。
示例代码(使用线性插值,C ++):
#include <algorithm>
#include <cmath>
Color interpolateRGB(Color from, Color to, float t)
{
// Clamp __t__ to range [0,1]
t = std::max(std::min(0.f, t), 1.f);
// Interpolate each RGB component
uint8_t r = std::roundf(from.r * (1-t) + to.r * t);
uint8_t g = std::roundf(from.g * (1-t) + to.g * t);
uint8_t b = std::roundf(from.b * (1-t) + to.b * t);
return Color(r, g, b);
}
void fillWithGradient(Image& img, Color from, Color to)
{
for(size_t row = 0; row < img.numRows(); ++row)
{
Color value = interpolateRGB(from, to, row / (img.numRows()-1));
// Set all pixels of this row to __value__
for(size_t col = 0; col < img.numCols(); ++col)
{
img.setPixel(row, col, value);
}
}
}
答案 1 :(得分:2)
基本想法是使用r
的其余部分n/(m-1)
,并在每次迭代时将其添加到n
:
#include <iostream>
#include <vector>
using namespace std;
vector<int> gradient( int n, int m ) {
div_t q { 0, 0 };
vector<int> grad(m);
for( int i=1 ; i<m ; ++i ) {
q = div( n + q.rem, m-1 );
grad[i] = grad[i-1] + q.quot;
}
return grad;
}
int main() {
for( int i : gradient(255,10) ) cout << i << ' ';
cout << '\n';
return 0;
}
输出:
0 28 56 85 113 141 170 198 226 255